<template>
    <!-- Add this error display section before the main content -->
    <div v-if="initError" class="error-container">
        <div class="error-content">
            <div class="error-message">
                <el-icon class="error-icon">
                    <Warning />
                </el-icon>
                <div class="error-text">
                    <h3>数据加载失败</h3>
                    <p>无法加载客户交易数据，请检查网络连接或稍后重试</p>
                </div>
            </div>
            <el-button type="primary" icon="Refresh" @click="retryInit" style="margin-top: 15px">
                重新加载
            </el-button>
        </div>
    </div>
    <div v-else class="metal-combine-container-wrapper " style="height: 100%; overflow: auto;">
        <div class="metal-combine-container excel-container" style="min-width: 800px;">
            <div class="excel-toolbar">

                <span style="  padding-left: 5px; margin-right: 120px; font-weight: bold;"> {{ targetObj?.name }}
                </span>

                <!--- 
                <el-button-group>
                    <el-button :icon="CopyDocument" @click="copyCell"></el-button>
                    <el-button :icon="DocumentCopy" @click="pasteCell"></el-button>
                </el-button-group>
                <el-button-group style="margin-left: 10px;">
                    <el-button :icon="Delete" @click="clearCell"></el-button>
                </el-button-group>
                <el-button style="margin-left: 20px;" @click="addRow">添加行</el-button>
                -->
                <el-button style="margin-left: 10px;" icon="Refresh" @click="refreshList">刷新列表</el-button>

                <!-- Add the save button here 
                <el-button type="primary" style="margin-left: 20px;" :disabled="!customerTransitionMgr?.isEdited"
                    @click="saveData">
                    保存
                </el-button>
                -->
                <el-button type="primary" style="margin-left: 20px;" @click="createOrder()">
                    新建
                </el-button>

                <!-- Collapsible Menu Trigger -->
                <div style="float: right;">
                    <el-tooltip :content="showCommoditySettings ? '收起设置' : '更多设置'" placement="top">
                        <el-button :icon="showCommoditySettings ? 'ArrowUp' : 'ArrowDown'"
                            @click="showCommoditySettings = !showCommoditySettings" circle>
                        </el-button>
                    </el-tooltip>
                </div>
                <div style="clear: both;"></div>
            </div>

            <!-- Collapsible Commodity Visibility Control -->
            <el-collapse-transition>
                <div>
                    <div v-show="showCommoditySettings" style="padding: 0 24px; width: 100%;">
                        <div
                            style="border: 1px solid #dcdfe6; border-radius: 4px; margin-top: 5px; margin-bottom: 10px; padding: 15px;">
                            <div style="display: flex; flex-wrap: wrap; gap: 20px; align-items: center;">
                                <span>商品列显示设置:</span>
                                <div v-for="commodity in metalCommodities" :key="commodity.id"
                                    style="display: flex; align-items: center; gap: 8px;">
                                    <span style="font-weight: 500;">{{ commodity.standard }}:</span>
                                    <el-checkbox-group v-model="visibleSalesCommodities">
                                        <el-checkbox :label="commodity.id">销售</el-checkbox>
                                    </el-checkbox-group>
                                    <el-checkbox-group v-model="visiblePurchaseCommodities">
                                        <el-checkbox :label="commodity.id">回购</el-checkbox>
                                    </el-checkbox-group>
                                </div>
                            </div>
                        </div>
                    </div>
                    <!-- Add new section for metal fund account visibility settings -->
                    <div v-show="showCommoditySettings" style="padding: 0 24px; width: 100%;">
                        <div
                            style="border: 1px solid #dcdfe6; border-radius: 4px; margin-top: 5px; margin-bottom: 10px; padding: 15px;">
                            <div style="display: flex; flex-wrap: wrap; gap: 20px; align-items: center;">
                                <span>收支列显示设置:</span>
                                <div v-for="commodity in metalCommodities" :key="commodity.id + '_fund'"
                                    style="display: flex; align-items: center; gap: 8px;">
                                    <span style="font-weight: 500;">{{ commodity.standard }}:</span>

                                    <el-checkbox-group v-model="visibleMetalInFundAccounts">
                                        <el-checkbox :label="commodity.metalAccountTypeId">来料</el-checkbox>
                                    </el-checkbox-group>

                                    <el-checkbox-group v-model="visibleMetalOutFundAccounts">
                                        <el-checkbox :label="commodity.metalAccountTypeId">付料</el-checkbox>
                                    </el-checkbox-group>

                                </div>
                                <div style="display: flex; align-items: center; gap: 8px;">
                                    <span style="font-weight: 500;"> 其他:</span>

                                    <el-checkbox-group v-model="visibleMetalInFundAccounts">
                                        <el-checkbox :label="MetalFeeTypeDefinition.SwapFee.code">仓息</el-checkbox>
                                    </el-checkbox-group>



                                </div>
                            </div>
                        </div>
                    </div>
                    <!---
                    <div v-show="showCommoditySettings" style="padding: 0 24px; width: 100%;">
                        <div
                            style="border: 1px solid #dcdfe6; border-radius: 4px; margin-top: 5px; margin-bottom: 10px; padding: 15px;">
                            <span> 结算记录:</span>
                            <div v-for="peroid in periodRecords" :key="peroid.id"
                                style="display: flex; align-items: center; gap: 8px;">
                                <span style="font-weight: 500;">{{ peroid.name }}:</span>

                                <el-checkbox-group v-model="visibleSalesCommodities">
                                    <el-checkbox :label="peroid.id">显示</el-checkbox>
                                </el-checkbox-group>

                            </div>
                        </div>
                    </div>
                    -->
                </div>
            </el-collapse-transition>

            <div class="excel-table-container-wrapper">
                <div class="excel-table-header" :style="{ width: tableWidth + 'px' }">
                    <table class="excel-table" :style="{ width: tableWidth + 'px' }">
                        <thead>
                            <tr>
                                <!-- 更新模板中的表头部分，添加拖拽手柄 -->
                                <th class="header-cell corner-cell" :style="{ width: rowHeaderWidth }">
                                    <div class="header-content">
                                        <span>#</span>
                                        <div class="resize-handle" @mousedown="startResize($event, 0)"></div>
                                    </div>
                                </th>
                                <th class="header-cell" :style="{ width: (columnWidths[0] || 120) + 'px' }">
                                    <div class="header-content">
                                        <span>业务日期</span>
                                        <div class="resize-handle" @mousedown="startResize($event, 0)"></div>
                                    </div>
                                </th>
                                <th class="header-cell" :style="{ width: (columnWidths[1] || 120) + 'px' }">
                                    <div class="header-content">
                                        <span>摘要</span>
                                        <div class="resize-handle" @mousedown="startResize($event, 1)"></div>
                                    </div>
                                </th>

                                <!-- 金属商品列 -->
                                <template v-for="(commodity, commodityIndex) in metalCommodities" :key="commodity.id">
                                    <!-- 销售组 -->
                                    <template v-if="visibleSalesCommodities.includes(commodity.id)">
                                        <th class="header-cell sales-group"
                                            :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.SalesCommodityCount, commodityIndex)] || 120) + 'px' }">
                                            <div class="header-content">
                                                <span>销售{{ commodity.standard }}</span>
                                                <div class="resize-handle"
                                                    @mousedown="startResize($event, getColumnIndex(TransactionCellType.SalesCommodityCount, commodityIndex))">
                                                </div>
                                            </div>
                                        </th>
                                        <th class="header-cell sales-group"
                                            :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.SaleCommodityPrice, commodityIndex)] || 120) + 'px' }">
                                            <div class="header-content">
                                                <span>单价</span>
                                                <div class="resize-handle"
                                                    @mousedown="startResize($event, getColumnIndex(TransactionCellType.SaleCommodityPrice, commodityIndex))">
                                                </div>
                                            </div>
                                        </th>
                                        <th class="header-cell sales-group"
                                            :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, commodityIndex)] || 120) + 'px' }">
                                            <div class="header-content">
                                                <span>应收货款</span>
                                                <div class="resize-handle"
                                                    @mousedown="startResize($event, getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, commodityIndex))">
                                                </div>
                                            </div>
                                        </th>
                                    </template>

                                    <!-- 回购组 -->
                                    <template v-if="visiblePurchaseCommodities.includes(commodity.id)">
                                        <th class="header-cell purchase-group"
                                            :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.PurchaseCommodityCount, commodityIndex)] || 120) + 'px' }">
                                            <div class="header-content">
                                                <span>回购{{ commodity.standard }}</span>
                                                <div class="resize-handle"
                                                    @mousedown="startResize($event, getColumnIndex(TransactionCellType.PurchaseCommodityCount, commodityIndex))">
                                                </div>
                                            </div>
                                        </th>
                                        <th class="header-cell purchase-group"
                                            :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.PurchaseCommodityPrice, commodityIndex)] || 120) + 'px' }">
                                            <div class="header-content">
                                                <span>单价</span>
                                                <div class="resize-handle"
                                                    @mousedown="startResize($event, getColumnIndex(TransactionCellType.PurchaseCommodityPrice, commodityIndex))">
                                                </div>
                                            </div>
                                        </th>
                                        <th class="header-cell purchase-group"
                                            :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, commodityIndex)] || 120) + 'px' }">
                                            <div class="header-content">
                                                <span>应付金额</span>
                                                <div class="resize-handle"
                                                    @mousedown="startResize($event, getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, commodityIndex))">
                                                </div>
                                            </div>
                                        </th>
                                    </template>
                                </template>

                                <!-- 贵金属收支 -->
                                <template v-for="(commodity, commodityIndex) in metalCommodities"
                                    :key="commodity.id + '_fund_group'">
                                    <!-- 来料列 -->
                                    <th v-if="visibleMetalInFundAccounts.includes(commodity.metalAccountTypeId)"
                                        class="header-cell metal-in-group"
                                        :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.MetalIn, commodityIndex)] || 120) + 'px' }">
                                        <div class="header-content">
                                            <span>来{{ commodity.standard }}</span>
                                            <div class="resize-handle"
                                                @mousedown="startResize($event, getColumnIndex(TransactionCellType.MetalIn, commodityIndex))">
                                            </div>
                                        </div>
                                    </th>

                                    <!-- 付料列 -->
                                    <th v-if="visibleMetalOutFundAccounts.includes(commodity.metalAccountTypeId)"
                                        class="header-cell metal-out-group"
                                        :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.MetalOut, commodityIndex)] || 120) + 'px' }">
                                        <div class="header-content">
                                            <span>付{{ commodity.standard }}</span>
                                            <div class="resize-handle"
                                                @mousedown="startResize($event, getColumnIndex(TransactionCellType.MetalOut, commodityIndex))">
                                            </div>
                                        </div>
                                    </th>
                                </template>

                                <th class="header-cell"
                                    :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.Receipt)] || 120) + 'px' }">
                                    <div class="header-content">
                                        <span>来款</span>
                                        <div class="resize-handle"
                                            @mousedown="startResize($event, getColumnIndex(TransactionCellType.Receipt))">
                                        </div>
                                    </div>
                                </th>
                                <th class="header-cell"
                                    :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.Payment)] || 120) + 'px' }">
                                    <div class="header-content">
                                        <span>已付款</span>
                                        <div class="resize-handle"
                                            @mousedown="startResize($event, getColumnIndex(TransactionCellType.Payment))">
                                        </div>
                                    </div>
                                </th>

                                <!-- Add this in the table header section, after the existing columns but before the closing </tr> tag -->
                                <th v-if="visibleMetalInFundAccounts.includes(MetalFeeTypeDefinition.SwapFee.code)"
                                    class="header-cell"
                                    :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.SwapFee)] || 120) + 'px' }">
                                    <div class="header-content">
                                        <span>仓息</span>
                                        <div class="resize-handle"
                                            @mousedown="startResize($event, getColumnIndex(TransactionCellType.SwapFee))">
                                        </div>
                                    </div>
                                </th>

                                <!-- 贵金属存欠料 -->
                                <template v-for="(commodity, commodityIndex) in metalCommodities"
                                    :key="commodity.id + '_balance_group'">
                                    <th v-if="visibleMetalInFundAccounts.includes(commodity.metalAccountTypeId)|| visibleMetalOutFundAccounts.includes(commodity.metalAccountTypeId)"
                                        class="header-cell metal-in-group"
                                        :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.MetalBanlance, commodityIndex)] || 120) + 'px' }">
                                        <div class="header-content">
                                            <span>存欠{{ commodity.standard }}</span>
                                            <div class="resize-handle"
                                                @mousedown="startResize($event, getColumnIndex(TransactionCellType.MetalBanlance, commodityIndex))">
                                            </div>
                                        </div>
                                    </th>
                                </template>

                                <th class="header-cell"
                                    :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.Balance)] || 120) + 'px' }">
                                    <div class="header-content">
                                        <span>存欠款</span>
                                        <div class="resize-handle"
                                            @mousedown="startResize($event, getColumnIndex(TransactionCellType.Balance))">
                                        </div>
                                    </div>
                                </th>
                                <th class="header-cell"
                                    :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.Remark)] || 120) + 'px' }">
                                    <div class="header-content">
                                        <span>备注</span>
                                        <div class="resize-handle"
                                            @mousedown="startResize($event, getColumnIndex(TransactionCellType.Remark))">
                                        </div>
                                    </div>
                                </th>
                            </tr>
                        </thead>
                    </table>
                </div>

                <div class="excel-table-container" ref="tableContainer" tabindex="0" @keydown.delete="handleDeleteKey"
                    @keydown="handleGlobalKeydown" :style="{ width: tableWidth + 'px' }">
                    <table class="excel-table" :style="{ width: tableWidth + 'px' }">
                        <tbody>
                            <tr v-for="(row, rowIndex) in dataList" :key="rowIndex">
                                <td class="header-cell" :class="{ 'edited-row': row.isEdited }"
                                    :style="{ width: rowHeaderWidth }"
                                    @contextmenu.prevent="showContextMenu($event, rowIndex)">
                                    {{ rowIndex + 1 }}
                                </td>

                                <td :class="[getCellClass(rowIndex, 0), { 'disabled-cell': row.isPeriodInitial }]"
                                    @click="selectCell(rowIndex, 0)" @dblclick="startEdit(rowIndex, 0)"
                                    :style="{ width: (columnWidths[0] || 120) + 'px' }">
                                    <el-date-picker v-if="!row.isPeriodInitial && hasEditPermission()"
                                        v-model="row.operateDateString" type="date" placeholder="" :clearable="true"
                                        format="YYYY-MM-DD HH:mm" value-format="YYYY-MM-DD HH:mm" style="width: 100%" />
                                    <span v-else-if="!row.isPeriodInitial" style="font-size: 13px;">{{
                                        formatDate(row.operateDate)
                                    }}</span>


                                </td>
                                <!-- 摘要-->
                                <td :class="[getCellClass(rowIndex, 1), { 'disabled-cell': row.isPeriodInitial }]"
                                    @click="selectCell(rowIndex, 1)" @dblclick="startEdit(rowIndex, 1)"
                                    :style="{ width: (columnWidths[1] || 120) + 'px' }">
                                    <input-cell v-if="isEditing(rowIndex, 1)" :model-value="row.title"
                                        :excel-cell-start-edit-value="cellInitValueSet[`${rowIndex}_1`]"
                                        @update:model-value="value => {
                                            cellInitValueSet[`${rowIndex}_1`] = null;
                                            row.title = value
                                        }" :ref="el => setEditInputRef(el, rowIndex, 1
                                        )" @blur="finishEdit(rowIndex, 1)" @keydown.enter="finishEdit(rowIndex, 1)"
                                        @keydown.tab="handleTabKey($event, rowIndex, 1)" @keydown.esc="cancelEdit"
                                        @keydown.up="handleArrowKey($event, rowIndex, 1, 'up')"
                                        @keydown.down="handleArrowKey($event, rowIndex, 1, 'down')"
                                        @keydown.left="handleArrowKey($event, rowIndex, 1, 'left')"
                                        @keydown.right="handleArrowKey($event, rowIndex, 1, 'right')" class="cell-input"
                                        :readonly="true" :background-color="'#e6f7ff'" :border="'none'" :padding="'0px'"
                                        :text-align="'left'" :no-border="true" />
                                    <span v-else style="font-size: 13px;">{{ row.title ?? '' }}</span>
                                </td>

                                <!-- Metal Commodity Columns 贵金属列-->
                                <template v-for="(commodity, colIndex) in metalCommodities" :key="commodity.id">
                                    <!-- Sales Group  销售 -->
                                    <template v-if="visibleSalesCommodities.includes(commodity.id)">
                                        <!-- Sales Quantity -->
                                        <td :class="[getCellClass(rowIndex, getColumnIndex(TransactionCellType.SalesCommodityCount, colIndex)), { 'disabled-cell': row.isPeriodInitial }]"
                                            @click="selectCell(rowIndex, getColumnIndex(TransactionCellType.SalesCommodityCount, colIndex))"
                                            @dblclick="startEdit(rowIndex, getColumnIndex(TransactionCellType.SalesCommodityCount, colIndex))"
                                            :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.SalesCommodityCount, colIndex)] || 120) + 'px' }">
                                            <input-cell
                                                v-if="!row.isPeriodInitial && isEditing(rowIndex, getColumnIndex(TransactionCellType.SalesCommodityCount, colIndex))"
                                                :model-value="row.getSalesBatchByCommodityId(commodity.id)?.count?.value ?? ''"
                                                :excel-cell-start-edit-value="cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.SalesCommodityCount, colIndex)}`]"
                                                @update:model-value="value => {
                                                    cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.SalesCommodityCount, colIndex)}`] = null;
                                                    row.getSalesBatchByCommodityId(commodity.id).setCount(new CsDouble(value, countPrecision));
                                                    row.updateOrderInfo(metalCommodities);
                                                    customerTransitionMgr.updateTransData();
                                                }" :ref="el => setEditInputRef(el, rowIndex, getColumnIndex(TransactionCellType.SalesCommodityCount, colIndex)
                                                )"
                                                @blur="finishEdit(rowIndex, getColumnIndex(TransactionCellType.SalesCommodityCount, colIndex))"
                                                @keydown.enter="finishEdit(rowIndex, getColumnIndex(TransactionCellType.SalesCommodityCount, colIndex))"
                                                @keydown.tab="handleTabKey($event, rowIndex, getColumnIndex(TransactionCellType.SalesCommodityCount, colIndex))"
                                                @keydown.esc="cancelEdit"
                                                @keydown.up="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SalesCommodityCount, colIndex), 'up')"
                                                @keydown.down="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SalesCommodityCount, colIndex), 'down')"
                                                @keydown.left="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SalesCommodityCount, colIndex), 'left')"
                                                @keydown.right="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SalesCommodityCount, colIndex), 'right')"
                                                class="cell-input" :readonly="row.isPeriodInitial"
                                                :background-color="'#e6f7ff'" :border="'none'" :padding="'0px'"
                                                :text-align="'left'" :no-border="true" :number-mode="true"
                                                :precision="countPrecision" />
                                            <span v-else>
                                                {{ row.getSalesBatchByCommodityId(commodity.id)?.count?.value ?? '' }}
                                            </span>
                                        </td>

                                        <!-- Sales Price -->
                                        <td :class="[getCellClass(rowIndex, getColumnIndex(TransactionCellType.SaleCommodityPrice, colIndex)), { 'disabled-cell': row.isPeriodInitial }]"
                                            @click="selectCell(rowIndex, getColumnIndex(TransactionCellType.SaleCommodityPrice, colIndex))"
                                            @dblclick="startEdit(rowIndex, getColumnIndex(TransactionCellType.SaleCommodityPrice, colIndex))"
                                            :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.SaleCommodityPrice, colIndex)] || 120) + 'px' }">
                                            <input-cell
                                                v-if="!row.isPeriodInitial && isEditing(rowIndex, getColumnIndex(TransactionCellType.SaleCommodityPrice, colIndex))"
                                                :model-value="row.getSalesBatchByCommodityId(commodity.id)?.singlePriceAfterTax?.value ?? ''"
                                                :excel-cell-start-edit-value="cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.SaleCommodityPrice, colIndex)}`]"
                                                @update:model-value="value => {
                                                    cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.SaleCommodityPrice, colIndex)}`] = null;
                                                    row.getSalesBatchByCommodityId(commodity.id).setSinglePriceAfterTax(new CsFundDouble(value, fundPrecision));
                                                    row.updateOrderInfo(metalCommodities);
                                                    customerTransitionMgr.updateTransData();
                                                }"
                                                :ref="el => setEditInputRef(el, rowIndex, getColumnIndex(TransactionCellType.SaleCommodityPrice, colIndex))"
                                                @blur="finishEdit(rowIndex, getColumnIndex(TransactionCellType.SaleCommodityPrice, colIndex))"
                                                @keydown.enter="finishEdit(rowIndex, getColumnIndex(TransactionCellType.SaleCommodityPrice, colIndex))"
                                                @keydown.tab="handleTabKey($event, rowIndex, getColumnIndex(TransactionCellType.SaleCommodityPrice, colIndex))"
                                                @keydown.esc="cancelEdit"
                                                @keydown.up="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SaleCommodityPrice, colIndex), 'up')"
                                                @keydown.down="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SaleCommodityPrice, colIndex), 'down')"
                                                @keydown.left="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SaleCommodityPrice, colIndex), 'left')"
                                                @keydown.right="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SaleCommodityPrice, colIndex), 'right')"
                                                class="cell-input" :readonly="row.isPeriodInitial"
                                                :background-color="'#e6f7ff'" :border="'none'" :padding="'0px'"
                                                :text-align="'left'" :no-border="true" :number-mode="true"
                                                :precision="countPrecision" />
                                            <span v-else>
                                                {{
                                                    row.getSalesBatchByCommodityId(commodity.id)?.singlePriceAfterTax?.value
                                                    ?? '' }}
                                            </span>
                                        </td>

                                        <!-- Sales Amount 应收货款 -->
                                        <td :class="[getCellClass(rowIndex, getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, colIndex)), { 'disabled-cell': row.isPeriodInitial }]"
                                            @click="selectCell(rowIndex, getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, colIndex))"
                                            @dblclick="startEdit(rowIndex, getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, colIndex))"
                                            :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, colIndex)] || 120) + 'px' }">
                                            <input-cell
                                                v-if="!row.isPeriodInitial && isEditing(rowIndex, getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, colIndex))"
                                                :model-value="row.getSalesBatchByCommodityId(commodity.id)?.batchPriceWithTax?.value ?? ''"
                                                :excel-cell-start-edit-value="cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, colIndex)}`]"
                                                @update:model-value="value => {
                                                    cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, colIndex)}`] = null;
                                                    row.getSalesBatchByCommodityId(commodity.id).setBatchPriceWithTax(new CsFundDouble(value, fundPrecision));
                                                    row.updateOrderInfo(metalCommodities);
                                                    customerTransitionMgr.updateTransData();

                                                }"
                                                :ref="el => setEditInputRef(el, rowIndex, getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, colIndex))"
                                                @blur="finishEdit(rowIndex, getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, colIndex))"
                                                @keydown.enter="finishEdit(rowIndex, getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, colIndex))"
                                                @keydown.tab="handleTabKey($event, rowIndex, getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, colIndex))"
                                                @keydown.esc="cancelEdit"
                                                @keydown.up="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, colIndex), 'up')"
                                                @keydown.down="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, colIndex), 'down')"
                                                @keydown.left="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, colIndex), 'left')"
                                                @keydown.right="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SalesCommodityBatchPrice, colIndex), 'right')"
                                                class="cell-input" :readonly="row.isPeriodInitial"
                                                :background-color="'#e6f7ff'" :border="'none'" :padding="'0px'"
                                                :text-align="'left'" :no-border="true" :number-mode="true"
                                                :precision="countPrecision" />
                                            <span v-else>
                                                {{
                                                    row.getSalesBatchByCommodityId(commodity.id)?.batchPriceWithTax?.value
                                                    ?? '' }}
                                            </span>
                                        </td>
                                    </template>

                                    <!-- Purchase Group -->
                                    <template v-if="visiblePurchaseCommodities.includes(commodity.id)">
                                        <!-- Purchase Quantity -->
                                        <td :class="[getCellClass(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityCount, colIndex)), { 'disabled-cell': row.isPeriodInitial }]"
                                            @click="selectCell(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityCount, colIndex))"
                                            @dblclick="startEdit(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityCount, colIndex))"
                                            :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.PurchaseCommodityCount, colIndex)] || 120) + 'px' }">
                                            <input-cell
                                                v-if="!row.isPeriodInitial && isEditing(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityCount, colIndex))"
                                                :model-value="row.getPurchaseBatchByCommodityId(commodity.id)?.count?.value ?? ''"
                                                :excel-cell-start-edit-value="cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.PurchaseCommodityCount, colIndex)}`]"
                                                @update:model-value="value => {
                                                    cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.PurchaseCommodityCount, colIndex)}`] = null;
                                                    row.getPurchaseBatchByCommodityId(commodity.id).setCount(new CsDouble(value, countPrecision));
                                                    row.updateOrderInfo(metalCommodities);
                                                    customerTransitionMgr.updateTransData();

                                                }"
                                                :ref="el => setEditInputRef(el, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityCount, colIndex))"
                                                @blur="finishEdit(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityCount, colIndex))"
                                                @keydown.enter="finishEdit(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityCount, colIndex))"
                                                @keydown.tab="handleTabKey($event, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityCount, colIndex))"
                                                @keydown.esc="cancelEdit"
                                                @keydown.up="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityCount, colIndex), 'up')"
                                                @keydown.down="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityCount, colIndex), 'down')"
                                                @keydown.left="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityCount, colIndex), 'left')"
                                                @keydown.right="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityCount, colIndex), 'right')"
                                                class="cell-input" :readonly="row.isPeriodInitial"
                                                :background-color="'#e6f7ff'" :border="'none'" :padding="'0px'"
                                                :text-align="'left'" :no-border="true" :number-mode="true"
                                                :precision="countPrecision" />
                                            <span v-else>
                                                {{ row.getPurchaseBatchByCommodityId(commodity.id)?.count?.value ?? ''
                                                }}
                                            </span>
                                        </td>

                                        <!-- Purchase Price -->
                                        <td :class="[getCellClass(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityPrice, colIndex)), { 'disabled-cell': row.isPeriodInitial }]"
                                            @click="selectCell(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityPrice, colIndex))"
                                            @dblclick="startEdit(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityPrice, colIndex))"
                                            :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.PurchaseCommodityPrice, colIndex)] || 120) + 'px' }">
                                            <input-cell
                                                v-if="!row.isPeriodInitial && isEditing(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityPrice, colIndex))"
                                                :model-value="row.getPurchaseBatchByCommodityId(commodity.id)?.singlePriceAfterTax?.value ?? ''"
                                                :excel-cell-start-edit-value="cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.PurchaseCommodityPrice, colIndex)}`]"
                                                @update:model-value="value => {
                                                    cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.PurchaseCommodityPrice, colIndex)}`] = null;
                                                    row.getPurchaseBatchByCommodityId(commodity.id).setSinglePriceAfterTax(new CsFundDouble(value, fundPrecision));
                                                    row.updateOrderInfo(metalCommodities);
                                                    customerTransitionMgr.updateTransData();
                                                }"
                                                :ref="el => setEditInputRef(el, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityPrice, colIndex))"
                                                @blur="finishEdit(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityPrice, colIndex))"
                                                @keydown.enter="finishEdit(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityPrice, colIndex))"
                                                @keydown.tab="handleTabKey($event, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityPrice, colIndex))"
                                                @keydown.esc="cancelEdit"
                                                @keydown.up="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityPrice, colIndex), 'up')"
                                                @keydown.down="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityPrice, colIndex), 'down')"
                                                @keydown.left="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityPrice, colIndex), 'left')"
                                                @keydown.right="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityPrice, colIndex), 'right')"
                                                class="cell-input" :readonly="row.isPeriodInitial"
                                                :background-color="'#e6f7ff'" :border="'none'" :padding="'0px'"
                                                :text-align="'left'" :no-border="true" :number-mode="true"
                                                :precision="countPrecision" />
                                            <span v-else>
                                                {{
                                                    row.getPurchaseBatchByCommodityId(commodity.id)?.singlePriceAfterTax?.value
                                                    ?? '' }}
                                            </span>
                                        </td>

                                        <!-- Purchase Amount -->
                                        <td :class="[getCellClass(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, colIndex)), { 'disabled-cell': row.isPeriodInitial }]"
                                            @click="selectCell(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, colIndex))"
                                            @dblclick="startEdit(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, colIndex))"
                                            :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, colIndex)] || 120) + 'px' }">
                                            <input-cell
                                                v-if="!row.isPeriodInitial && isEditing(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, colIndex))"
                                                :model-value="row.getPurchaseBatchByCommodityId(commodity.id)?.batchPriceWithTax?.value ?? ''"
                                                :excel-cell-start-edit-value="cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, colIndex)}`]"
                                                @update:model-value="value => {
                                                    cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, colIndex)}`] = null;
                                                    row.getPurchaseBatchByCommodityId(commodity.id).setBatchPriceWithTax(new CsFundDouble(value, fundPrecision));
                                                    row.updateOrderInfo(metalCommodities);
                                                    customerTransitionMgr.updateTransData();

                                                }"
                                                :ref="el => setEditInputRef(el, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, colIndex))"
                                                @blur="finishEdit(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, colIndex))"
                                                @keydown.enter="finishEdit(rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, colIndex))"
                                                @keydown.tab="handleTabKey($event, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, colIndex))"
                                                @keydown.esc="cancelEdit"
                                                @keydown.up="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, colIndex), 'up')"
                                                @keydown.down="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, colIndex), 'down')"
                                                @keydown.left="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, colIndex), 'left')"
                                                @keydown.right="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.PurchaseCommodityBatchPrice, colIndex), 'right')"
                                                class="cell-input" :readonly="row.isPeriodInitial"
                                                :background-color="'#e6f7ff'" :border="'none'" :padding="'0px'"
                                                :text-align="'left'" :no-border="true" :number-mode="true"
                                                :precision="countPrecision" />
                                            <span v-else>
                                                {{
                                                    row.getPurchaseBatchByCommodityId(commodity.id)?.batchPriceWithTax?.value
                                                    ?? '' }}
                                            </span>
                                        </td>
                                    </template>
                                </template>

                                <!-- 贵金属收支 -->
                                <template v-for="(commodity, colIndex) in metalCommodities"
                                    :key="commodity.id + '_fund_group'">
                                    <!-- In Count Column (来料) -->
                                    <td v-if="visibleMetalInFundAccounts.includes(commodity.metalAccountTypeId)"
                                        :class="[getCellClass(rowIndex, getColumnIndex(TransactionCellType.MetalIn, colIndex)), { 'disabled-cell': row.isPeriodInitial }]"
                                        @click="selectCell(rowIndex, getColumnIndex(TransactionCellType.MetalIn, colIndex))"
                                        @dblclick="startEdit(rowIndex, getColumnIndex(TransactionCellType.MetalIn, colIndex))"
                                        :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.MetalIn, colIndex)] || 120) + 'px' }">
                                        <input-cell
                                            v-if="!row.isPeriodInitial && isEditing(rowIndex, getColumnIndex(TransactionCellType.MetalIn, colIndex))"
                                            :model-value="getMetalInCount(row, commodity.metalAccountTypeId)"
                                            :excel-cell-start-edit-value="cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.MetalIn, colIndex)}`]"
                                            @update:model-value="value => {
                                                cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.MetalIn, colIndex)}`] = null;
                                                updateMetalInCount(row, commodity.metalAccountTypeId, value);
                                                row.updateOrderInfo(metalCommodities);
                                                customerTransitionMgr.updateTransData();
                                            }"
                                            :ref="el => setEditInputRef(el, rowIndex, getColumnIndex(TransactionCellType.MetalIn, colIndex))"
                                            @blur="finishEdit(rowIndex, getColumnIndex(TransactionCellType.MetalIn, colIndex))"
                                            @keydown.enter="finishEdit(rowIndex, getColumnIndex(TransactionCellType.MetalIn, colIndex))"
                                            @keydown.tab="handleTabKey($event, rowIndex, getColumnIndex(TransactionCellType.MetalIn, colIndex))"
                                            @keydown.esc="cancelEdit"
                                            @keydown.up="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.MetalIn, colIndex), 'up')"
                                            @keydown.down="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.MetalIn, colIndex), 'down')"
                                            @keydown.left="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.MetalIn, colIndex), 'left')"
                                            @keydown.right="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.MetalIn, colIndex), 'right')"
                                            class="cell-input" :readonly="row.isPeriodInitial"
                                            :background-color="'#e6f7ff'" :border="'none'" :padding="'0px'"
                                            :text-align="'left'" :no-border="true" :number-mode="true"
                                            :precision="countPrecision" />
                                        <span v-else>{{ getMetalInCount(row,
                                            commodity.metalAccountTypeId) }}</span>
                                    </td>

                                    <!-- Out Count Column (付料) -->
                                    <td v-if="visibleMetalOutFundAccounts.includes(commodity.metalAccountTypeId)"
                                        :class="[getCellClass(rowIndex, getColumnIndex(TransactionCellType.MetalOut, colIndex)), { 'disabled-cell': row.isPeriodInitial }]"
                                        @click="selectCell(rowIndex, getColumnIndex(TransactionCellType.MetalOut, colIndex))"
                                        @dblclick="startEdit(rowIndex, getColumnIndex(TransactionCellType.MetalOut, colIndex))"
                                        :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.MetalOut, colIndex)] || 120) + 'px' }">
                                        <input-cell
                                            v-if="!row.isPeriodInitial && isEditing(rowIndex, getColumnIndex(TransactionCellType.MetalOut, colIndex))"
                                            :model-value="getMetalOutCount(row, commodity.metalAccountTypeId)"
                                            :excel-cell-start-edit-value="cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.MetalOut, colIndex)}`]"
                                            @update:model-value="value => {
                                                cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.MetalOut, colIndex)}`] = null;
                                                updateMetalOutCount(row, commodity.metalAccountTypeId, value);
                                                row.updateOrderInfo(metalCommodities);
                                                customerTransitionMgr.updateTransData();
                                            }"
                                            :ref="el => setEditInputRef(el, rowIndex, getColumnIndex(TransactionCellType.MetalOut, colIndex))"
                                            @blur="finishEdit(rowIndex, getColumnIndex(TransactionCellType.MetalOut, colIndex))"
                                            @keydown.enter="finishEdit(rowIndex, getColumnIndex(TransactionCellType.MetalOut, colIndex))"
                                            @keydown.tab="handleTabKey($event, rowIndex, getColumnIndex(TransactionCellType.MetalOut, colIndex))"
                                            @keydown.esc="cancelEdit"
                                            @keydown.up="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.MetalOut, colIndex), 'up')"
                                            @keydown.down="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.MetalOut, colIndex), 'down')"
                                            @keydown.left="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.MetalOut, colIndex), 'left')"
                                            @keydown.right="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.MetalOut, colIndex), 'right')"
                                            class="cell-input" :readonly="row.isPeriodInitial"
                                            :background-color="'#e6f7ff'" :border="'none'" :padding="'0px'"
                                            :text-align="'left'" :no-border="true" :number-mode="true"
                                            :precision="countPrecision" />
                                        <span v-else>{{ getMetalOutCount(row, commodity.metalAccountTypeId) }}</span>
                                    </td>
                                </template>

                                <!-- 来款 3 贵金属起始index 每个贵金属 销购 来付  3+3+2 列 
                                 注意，input-cell 去除了下拉事件，因为 el-select 点击就触发了该事件，而且事件宿主是上级 div 无法判断是否
                                 是select 触发
                                 @blur="finishEdit(rowIndex, getColumnIndex(TransactionCellType.Receipt),$event)" 

                                 同时在通用 selectCell 里面清除了当前编辑的cell, 这样使得该cell 能够失去焦点
                                -->
                                <td :class="[getCellClass(rowIndex, getColumnIndex(TransactionCellType.Receipt)), { 'disabled-cell': row.isPeriodInitial }]"
                                    @click="selectCell(rowIndex, getColumnIndex(TransactionCellType.Receipt))"
                                    @dblclick="startEdit(rowIndex, getColumnIndex(TransactionCellType.Receipt))"
                                    :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.Receipt)] || 120) + 'px' }">
                                    <div v-if="!row.isPeriodInitial && isEditing(rowIndex, getColumnIndex(TransactionCellType.Receipt))"
                                        class="fundaccount-cell-container">

                                        <input-cell :model-value="row.receivedAmount?.value ?? ''"
                                            :excel-cell-start-edit-value="cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.Receipt)}`]"
                                            @update:model-value="value => {
                                                cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.Receipt)}`] = null;
                                                row.receivedAmount = new CsFundDouble(value, fundPrecision);
                                                row.updateOrderInfo(metalCommodities);
                                                customerTransitionMgr.updateTransData();
                                            }"
                                            :ref="el => setEditInputRef(el, rowIndex, getColumnIndex(TransactionCellType.Receipt))"
                                            @keydown.enter="finishEdit(rowIndex, getColumnIndex(TransactionCellType.Receipt))"
                                            @keydown.tab="handleTabKey($event, rowIndex, getColumnIndex(TransactionCellType.Receipt))"
                                            @keydown.esc="cancelEdit"
                                            @keydown.up="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Receipt), 'up')"
                                            @keydown.down="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Receipt), 'down')"
                                            @keydown.left="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Receipt), 'left')"
                                            @keydown.right="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Receipt), 'right')"
                                            class="cell-input" :readonly="row.isPeriodInitial"
                                            :background-color="'#e6f7ff'" :border="'none'" :padding="'0px'"
                                            :text-align="'left'" :no-border="true" :number-mode="true"
                                            :precision="fundPrecision" />

                                        <!-- Account selector dropdown 
                                         @visible-change="handleSelectVisibleChange" 和 finished 里面组合判断，保障了点击候选项后不会失去焦点 -->
                                        <!-- 
                                        <el-select v-model="row.receiptAccountId"
                                            @change="updateReceiptAccount(row, $event)"
                                            @visible-change="handleSelectVisibleChange" 
                                            class="account-selector"
                                            @blur="finishEdit(rowIndex, getColumnIndex(TransactionCellType.Receipt), $event)"
                                            :disabled="row.isPeriodInitial">
                                            <el-option v-for="account in receiptAccounts" :key="account.id"
                                                :label="account.name" :value="account.id" />
                                        </el-select>
                                        -->
                                        <fund-account-select v-model="row.fundAccountForReceive" prop="fundAccount"
                                            :fund-ui-action="fundUiAction" />
                                    </div>
                                    <div v-else class="receipt-display">
                                        <div>{{ row.receivedAmount?.value ?? '' }}</div>
                                        <div class="account-name" v-if="row.fundAccountForReceive">
                                            {{ row.fundAccountForReceive.name }}
                                        </div>
                                    </div>
                                </td>

                                <!-- 已付款 -->
                                <td :class="[getCellClass(rowIndex, getColumnIndex(TransactionCellType.Payment)), { 'disabled-cell': row.isPeriodInitial }]"
                                    @click="selectCell(rowIndex, getColumnIndex(TransactionCellType.Payment))"
                                    @dblclick="startEdit(rowIndex, getColumnIndex(TransactionCellType.Payment))"
                                    :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.Payment)] || 120) + 'px' }">
                                    <div v-if="!row.isPeriodInitial && isEditing(rowIndex, getColumnIndex(TransactionCellType.Payment))"
                                        class="fundaccount-cell-container">
                                        <input-cell :model-value="row.paymentAmount?.value ?? ''"
                                            :excel-cell-start-edit-value="cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.Payment)}`]"
                                            @update:model-value="value => {
                                                cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.Payment)}`] = null;
                                                row.paymentAmount = new CsFundDouble(value, fundPrecision);
                                                row.updateOrderInfo(metalCommodities);
                                                customerTransitionMgr.updateTransData();
                                            }"
                                            :ref="el => setEditInputRef(el, rowIndex, getColumnIndex(TransactionCellType.Payment))"
                                            @keydown.enter="finishEdit(rowIndex, getColumnIndex(TransactionCellType.Payment))"
                                            @keydown.tab="handleTabKey($event, rowIndex, getColumnIndex(TransactionCellType.Payment))"
                                            @keydown.esc="cancelEdit"
                                            @keydown.up="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Payment), 'up')"
                                            @keydown.down="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Payment), 'down')"
                                            @keydown.left="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Payment), 'left')"
                                            @keydown.right="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Payment), 'right')"
                                            class="cell-input" :readonly="row.isPeriodInitial"
                                            :background-color="'#e6f7ff'" :border="'none'" :padding="'0px'"
                                            :text-align="'left'" :no-border="true" :number-mode="true"
                                            :precision="fundPrecision" />


                                        <fund-account-select v-model="row.fundAccountForPayment" prop="fundAccount"
                                            :fund-ui-action="fundUiAction" />

                                    </div>
                                    <div v-else class="receipt-display">
                                        <div>{{ row.paymentAmount?.value ?? '' }}</div>
                                        <div class="account-name" v-if="row.fundAccountForPayment">
                                            {{ row.fundAccountForPayment.name }}
                                        </div>
                                    </div>
                                </td>

                                <!-- 仓息 -->
                                <td v-if="visibleMetalInFundAccounts.includes(MetalFeeTypeDefinition.SwapFee.code)"
                                    :class="[getCellClass(rowIndex, getColumnIndex(TransactionCellType.SwapFee)), { 'disabled-cell': row.isPeriodInitial }]"
                                    @click="selectCell(rowIndex, getColumnIndex(TransactionCellType.SwapFee))"
                                    @dblclick="startEdit(rowIndex, getColumnIndex(TransactionCellType.SwapFee))"
                                    :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.SwapFee)] || 120) + 'px' }">
                                    <input-cell
                                        v-if="!row.isPeriodInitial && isEditing(rowIndex, getColumnIndex(TransactionCellType.SwapFee))"
                                        :model-value="row.swapFee.fundDouble?.value ?? ''"
                                        :excel-cell-start-edit-value="cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.SwapFee)}`]"
                                        @update:model-value="value => {
                                            cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.SwapFee)}`] = null;
                                            row.swapFee.fundDouble = new CsFundDouble(value, fundPrecision);
                                            row.updateOrderInfo(metalCommodities);
                                            customerTransitionMgr.updateTransData();
                                        }"
                                        :ref="el => setEditInputRef(el, rowIndex, getColumnIndex(TransactionCellType.SwapFee))"
                                        @blur="finishEdit(rowIndex, getColumnIndex(TransactionCellType.SwapFee))"
                                        @keydown.enter="finishEdit(rowIndex, getColumnIndex(TransactionCellType.SwapFee))"
                                        @keydown.tab="handleTabKey($event, rowIndex, getColumnIndex(TransactionCellType.SwapFee))"
                                        @keydown.esc="cancelEdit"
                                        @keydown.up="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SwapFee), 'up')"
                                        @keydown.down="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SwapFee), 'down')"
                                        @keydown.left="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SwapFee), 'left')"
                                        @keydown.right="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.SwapFee), 'right')"
                                        class="cell-input" :readonly="row.isPeriodInitial" :background-color="'#e6f7ff'"
                                        :border="'none'" :padding="'0px'" :text-align="'left'" :no-border="true"
                                        :number-mode="true" :precision="fundPrecision" />
                                    <span v-else>{{ row.swapFee.fundDouble?.value ?? '' }}</span>
                                </td>

                                <!-- 贵金属存欠料 -->
                                <template v-for="(commodity, colIndex) in metalCommodities"
                                    :key="commodity.id + '_balance_group'">
                                    <td v-if="visibleMetalInFundAccounts.includes(commodity.metalAccountTypeId) || visibleMetalOutFundAccounts.includes(commodity.metalAccountTypeId)"
                                        :class="getCellClass(rowIndex, getColumnIndex(TransactionCellType.MetalBanlance, colIndex))"
                                        @click="selectCell(rowIndex, getColumnIndex(TransactionCellType.MetalBanlance, colIndex))"
                                        @dblclick="startEdit(rowIndex, getColumnIndex(TransactionCellType.MetalBanlance, colIndex))"
                                        :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.MetalBanlance, colIndex)] || 120) + 'px' }">
                                        <input-cell
                                            v-if="isEditing(rowIndex, getColumnIndex(TransactionCellType.MetalBanlance, colIndex))"
                                            :model-value="(getMetalBalance(row, commodity.metalAccountTypeId))"
                                            :excel-cell-start-edit-value="cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.MetalBanlance, colIndex)}`]"
                                            @update:model-value="value => {
                                                cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.MetalBanlance, colIndex)}`] = null;
                                                updateMetalBalance(row, commodity.metalAccountTypeId, value)
                                                customerTransitionMgr.updateTransData();
                                            }"
                                            :ref="el => setEditInputRef(el, rowIndex, getColumnIndex(TransactionCellType.MetalBanlance, colIndex))"
                                            @blur="finishEdit(rowIndex, getColumnIndex(TransactionCellType.MetalBanlance, colIndex))"
                                            @keydown.enter="finishEdit(rowIndex, getColumnIndex(TransactionCellType.MetalBanlance, colIndex))"
                                            @keydown.tab="handleTabKey($event, rowIndex, getColumnIndex(TransactionCellType.MetalBanlance, colIndex))"
                                            @keydown.esc="cancelEdit"
                                            @keydown.up="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.MetalBanlance, colIndex), 'up')"
                                            @keydown.down="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.MetalBanlance, colIndex), 'down')"
                                            @keydown.left="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.MetalBanlance, colIndex), 'left')"
                                            @keydown.right="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.MetalBanlance, colIndex), 'right')"
                                            class="cell-input" :readonly="!row.isPeriodInitial"
                                            :background-color="'#e6f7ff'" :border="'none'" :padding="'0px'"
                                            :text-align="'left'" :no-border="true" :number-mode="true"
                                            :precision="countPrecision" :zero-as-blank="false" />
                                        <span v-else>{{ getMetalBalance(row, commodity.metalAccountTypeId) }}</span>
                                    </td>
                                </template>

                                <!-- 存欠款 -->
                                <td :class="getCellClass(rowIndex, getColumnIndex(TransactionCellType.Balance))"
                                    @click="selectCell(rowIndex, getColumnIndex(TransactionCellType.Balance))"
                                    @dblclick="startEdit(rowIndex, getColumnIndex(TransactionCellType.Balance))"
                                    :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.Balance)] || 120) + 'px' }">
                                    <input-cell v-if="isEditing(rowIndex, getColumnIndex(TransactionCellType.Balance))"
                                        :model-value="row.balanceAfter?.value ?? ''"
                                        :excel-cell-start-edit-value="cellInitValueSet[`${rowIndex}_${rowIndex, getColumnIndex(TransactionCellType.Balance)}`]"
                                        @update:model-value="value => {
                                            cellInitValueSet[`${rowIndex}_${rowIndex, getColumnIndex(TransactionCellType.Balance)}`] = null;
                                            row.innerBalance = new CsFundDouble(value, fundPrecision);
                                            row.isEdited = true;
                                            customerTransitionMgr.updateTransData();
                                        }"
                                        :ref="el => setEditInputRef(el, rowIndex, getColumnIndex(TransactionCellType.Balance))"
                                        @blur="finishEdit(rowIndex, getColumnIndex(TransactionCellType.Balance))"
                                        @keydown.enter="finishEdit(rowIndex, getColumnIndex(TransactionCellType.Balance))"
                                        @keydown.tab="handleTabKey($event, rowIndex, getColumnIndex(TransactionCellType.Balance))"
                                        @keydown.esc="cancelEdit"
                                        @keydown.up="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Balance), 'up')"
                                        @keydown.down="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Balance), 'down')"
                                        @keydown.left="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Balance), 'left')"
                                        @keydown.right="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Balance), 'right')"
                                        class="cell-input" :readonly="!row.isPeriodInitial"
                                        :background-color="'#e6f7ff'" :border="'none'" :padding="'0px'"
                                        :text-align="'left'" :no-border="true" :number-mode="true"
                                        :precision="fundPrecision" :zero-as-blank="false" />
                                    <span v-else>{{ row.balanceAfter?.value ?? '' }}</span>
                                </td>

                                <!-- 备注 -->
                                <td :class="getCellClass(rowIndex, getColumnIndex(TransactionCellType.Remark))"
                                    @click="selectCell(rowIndex, getColumnIndex(TransactionCellType.Remark))"
                                    @dblclick="startEdit(rowIndex, getColumnIndex(TransactionCellType.Remark))"
                                    :style="{ width: (columnWidths[getColumnIndex(TransactionCellType.Remark)] || 120) + 'px' }">
                                    <input-cell v-if="isEditing(rowIndex, getColumnIndex(TransactionCellType.Remark))"
                                        :model-value="row.remark ?? ''"
                                        :excel-cell-start-edit-value="cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.Remark)}`]"
                                        @update:model-value="value => {
                                            cellInitValueSet[`${rowIndex}_${getColumnIndex(TransactionCellType.Remark)}`] = null;
                                            row.remark = value;
                                            row.isEdited = true;
                                            customerTransitionMgr.updateTransData();
                                        }"
                                        :ref="el => setEditInputRef(el, rowIndex, getColumnIndex(TransactionCellType.Remark),)"
                                        @blur="finishEdit(rowIndex, getColumnIndex(TransactionCellType.Remark))"
                                        @keydown.enter="finishEdit(rowIndex, getColumnIndex(TransactionCellType.Remark))"
                                        @keydown.tab="handleTabKey($event, rowIndex, getColumnIndex(TransactionCellType.Remark))"
                                        @keydown.esc="cancelEdit"
                                        @keydown.up="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Remark), 'up')"
                                        @keydown.down="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Remark), 'down')"
                                        @keydown.left="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Remark), 'left')"
                                        @keydown.right="handleArrowKey($event, rowIndex, getColumnIndex(TransactionCellType.Remark), 'right')"
                                        class="cell-input" :readonly="false" :background-color="'#e6f7ff'"
                                        :border="'none'" :padding="'0px'" :text-align="'left'" :no-border="true" />
                                    <span v-else>{{ row.remark ?? '' }}</span>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
            <!--
            <div class="excel-status-bar">
                <span v-if="selectedCell">Cell: {{ getCellAddress() }}</span>
                <span v-else>选择一个单元格</span>
            </div>
-->
            <!-- Replace your current pagination section with this -->
            <div v-if="showPagination" style="width: 80%; min-width: 600px; margin: 0 auto; padding: 0;">
                <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
                    v-model:limit="queryParams.pageSize" @pagination="getList" />
            </div>

            <!-- 右击菜单 -->
            <div v-if="contextMenu.visible" class="context-menu"
                :style="{ left: contextMenu.x + 'px', top: contextMenu.y + 'px' }" @contextmenu.prevent>
                <ul>
                    <li :class="{ 'disabled': !rowEditAble(contextMenu.rowIndex) }"
                        @click="rowEditAble(contextMenu.rowIndex) && editRow(contextMenu.rowIndex)">
                        <el-icon>
                            <Edit />
                        </el-icon>
                        编辑行
                    </li>

                    <li :class="{ 'disabled': !rowDeleteAble(contextMenu.rowIndex) }"
                        @click="rowDeleteAble(contextMenu.rowIndex) && deleteRow(contextMenu.rowIndex)">
                        <el-icon>
                            <Delete />
                        </el-icon>
                        删除行
                    </li>

                </ul>
            </div>

        </div>
    </div>

    <!-- 编辑窗口 -->
    <customer-transaction-dialog ref="transactionDialog" :is-edit-mode="isEditDialog"
        :metal-commodities="metalCommodities" :visible-sales-commodities="visibleSalesCommodities"
        :visible-purchase-commodities="visiblePurchaseCommodities"
        :visible-metal-in-fund-accounts="visibleMetalInFundAccounts"
        :visible-metal-out-fund-accounts="visibleMetalOutFundAccounts" :fund-precision="fundPrecision"
        :count-precision="countPrecision" :target-object="targetObj" :metal-ui-action="metalUiAction"
        :fund-ui-action="fundUiAction" @confirm="handleTransactionConfirm" />
</template>

<script>
import { ElMessage, ElMessageBox } from 'element-plus'
import { CopyDocument, DocumentCopy, Delete, Edit } from '@element-plus/icons-vue'
import { MetalUiAction } from '../../public/engine/uiAction/metalUiAction'
import { InventoryUiAction } from '../../public/engine/uiAction/inventoryUiAction'
import { CommonOrderStatus, OrderSortType, CombineOrderType } from '../../public/engine/common/docDefinition'
import { DataPage } from '../../public/network/communicationConverter'
import { MetalCombineOrder, MetalCombineOrderFilter } from '../../public/engine/metal/metalCombineOrder'
import { DateUtil } from '../../public/utils/dateUtil'
import EventBus from '../../public/engine/ipc/eventBus'
import WarehouseSelect from '../../public/views/componentsWeb/WarehouseSelect.vue'
import { deleteMetalCombineOrderNetworkCache } from '../../public/network/api'
import { Util } from '../../public/utils/util'
import { Engine } from '../../public/engine/engine'
import { uiNavigation } from '../../public/views/uiEntrance/uiNavigation'
import { CommodityUiAction } from '../../public/engine/uiAction/commodityUiAction'
import { SubCommodityFilter, SubCommodityMetalFilterTypeEnum } from '../../public/engine/commodity/subCommodity'
import InputCell from '../../public/views/componentsWeb/InputCell.vue'
import { Definition } from '../../public/engine/common/definition.js'
import { CsFundDouble } from '../../public/engine/common/csFundDouble'
import { CsDouble } from '../../public/engine/common/csDouble.js'
import { CustomerTransictionMgr, TransactionCellType } from '../../public/engine/metal/customerTransitionMgr'
import { markRaw } from 'vue'
import { FundUiAction } from '../../public/engine/uiAction/fundUiAction'
import FundAccountSelect from '../../public/views/componentsWeb/FundAccountSelect.vue'
import { MetalFeeTypeDefinition } from '../../public/engine/common/metalDefinition.js'
import CustomerTransactionDialog from './customerTransactionRecordDialog.vue'


export default {
    name: 'customerTransactionPage',

    components: {
        WarehouseSelect,
        InputCell,
        FundAccountSelect,
        CustomerTransactionDialog,
    },


    data() {
        return {
            CsFundDouble,
            CsDouble,
            MetalFeeTypeDefinition,
            targetObj: null,
            TransactionCellType,
            CopyDocument: markRaw(CopyDocument),
            DocumentCopy: markRaw(DocumentCopy),
            Delete: markRaw(Delete),
            Edit: markRaw(Edit),
            rowHeaderWidth: '60px',
            loading: false,
            total: 0,
            queryParams: {
                pageNum: 1,
                pageSize: 1000,   // 1000 条显示，除了极端场景都能显示
            },
            filter: new MetalCombineOrderFilter(),
            dateRange: [],
            dataList: [], // MetalCombineOrder 列表
            metalUiAction: new MetalUiAction(),
            inventoryUiAction: new InventoryUiAction(),
            CommonOrderStatus,
            OrderSortType,
            commodityUiAction: new CommodityUiAction(),
            metalCommodities: [],  // SubCommodity 贵金属商品列表
            visibleSalesCommodities: [],    // 控制销售组商品列的显示
            visiblePurchaseCommodities: [], // 控制回购组商品列的显示
            visibleMetalInFundAccounts: [],  // 控制贵金属来料账户列的显示
            visibleMetalOutFundAccounts: [], // 控制贵金属付料账户列的显示
            showCommoditySettings: false,   // 控制商品设置菜单的展开/收缩
            periodRecords: [
                { 'name': '2025年8月', 'id': 1 },
                { 'name': '2025年7月', 'id': 2 }
            ],
            customerTransitionMgr: null,
            initError: false,

            // Excel-like editing state
            selectedCell: null,
            editingCell: null,
            editValue: '',
            clipboard: null,
            editInput: null,
            typingMode: false,
            cellInitValueSet: {},  // cell 直接编辑时初始值
            columnIndexSet: {},    // 列index,
            columnIndexCellTypeSet: {}, // 列index 对应的 TransactionCellType, columnIndexSet 反向索引


            /*
            receiptAccounts: [
                { id: '1', name: '现金账户' },
                { id: '2', name: '银行账户1' },
                { id: '3', name: '银行账户2' }
            ],
            */

            selectDropdownVisible: false,


            // 列宽配置
            columnWidths: {}, // { [colIndex]: width }
            defaultColumnWidth: 60,  // 数据默认列宽
            dateColumnWidth: 80,     // 日期列宽
            titleColumnWidth: 80,    // 标题列宽
            remarkColumnWidth: 120,  // 备注列宽
            resizingColumn: null,
            resizingStartX: 0,
            resizingStartWidth: 0,
            fundUiAction: new FundUiAction(),

            contextMenu: {
                visible: false,
                x: 0,
                y: 0,
                rowIndex: -1
            },

            // ... existing data properties ...
            showTransactionDialog: false,
            isEditDialog: false,
            currentEditRow: null,
            currentEditRowIndex: -1
        }
    },
    mounted() {
        document.addEventListener('click', this.hideContextMenu);
        EventBus.on('metalCombineOrderUpdated', this.getList)
    },

    beforeUnmount() {
        document.removeEventListener('click', this.hideContextMenu);
        EventBus.off('metalCombineOrderUpdated', this.getList)
    },

    watch: {
        // Watch for changes in visible sales commodities
        visibleSalesCommodities: {
            handler(newVal, oldVal) {
                this.handleVisibilityChange('sales', newVal, oldVal);
            },
            deep: true
        },

        // Watch for changes in visible purchase commodities
        visiblePurchaseCommodities: {
            handler(newVal, oldVal) {
                this.handleVisibilityChange('purchase', newVal, oldVal);
            },
            deep: true
        },

        // Watch for changes in visible metal in fund accounts
        visibleMetalInFundAccounts: {
            handler(newVal, oldVal) {
                this.handleVisibilityChange('metalIn', newVal, oldVal);
            },
            deep: true
        },

        // Watch for changes in visible metal out fund accounts
        visibleMetalOutFundAccounts: {
            handler(newVal, oldVal) {
                this.handleVisibilityChange('metalOut', newVal, oldVal);
            },
            deep: true
        }
    },

    computed: {
        fixedColumnWith() {
            return 120;
        },

        showPagination() {
            return this.total > this.queryParams.pageSize;

        },

        /*
        tableHeight() {
            // Dynamically calculate table height based on whether pagination is shown
            return this.showPagination ? 'calc(100vh - 220px)' : 'calc(100vh - 160px)';
           
        },
        */

        fundPrecision() {
            return Definition.fundPrecision;
        },

        countPrecision() {
            return Definition.precision;
        },

        // 计算列宽
        tableWidth() {

            let widthV2 = 0;

            // console.log('------------> tableWidth');
            // Start with row header width
            let width = parseInt(this.rowHeaderWidth);

            // Add fixed columns (业务日期, 摘要, 来款, 已付款, 存欠款, 备注)
            width += 6 * this.fixedColumnWith;


            let currentIndex = 0; // Start after Date and Title columns
            widthV2 += parseInt(this.rowHeaderWidth);
            widthV2 += this.columnWidths[currentIndex++];
            widthV2 += this.columnWidths[currentIndex++];

            // Add metal commodity columns
            this.metalCommodities.forEach(commodity => {
                // Sales group (3 columns: quantity, price, amount)
                if (this.visibleSalesCommodities.includes(commodity.id)) {
                    width += 3 * this.fixedColumnWith;

                    widthV2 += this.columnWidths[currentIndex++];
                    widthV2 += this.columnWidths[currentIndex++];
                    widthV2 += this.columnWidths[currentIndex++];
                }
                else {
                    currentIndex += 3;
                }

                // Purchase group (3 columns: quantity, price, amount)
                if (this.visiblePurchaseCommodities.includes(commodity.id)) {
                    width += 3 * this.fixedColumnWith;

                    widthV2 += this.columnWidths[currentIndex++];
                    widthV2 += this.columnWidths[currentIndex++];
                    widthV2 += this.columnWidths[currentIndex++];
                }
                else {
                    currentIndex += 3;
                }
            });

            // Add metal fund account columns
            this.metalCommodities.forEach(commodity => {
                // In count column
                if (this.visibleMetalInFundAccounts.includes(commodity.metalAccountTypeId)) {
                    width += this.fixedColumnWith;
                    widthV2 += this.columnWidths[currentIndex++];
                }
                else {
                    currentIndex++;
                }

                // Out count column
                if (this.visibleMetalOutFundAccounts.includes(commodity.metalAccountTypeId)) {
                    width += this.fixedColumnWith;
                    widthV2 += this.columnWidths[currentIndex++];
                }
                else {
                    currentIndex++;
                }
            });

            // 仓息
            if (this.visibleMetalInFundAccounts.includes(MetalFeeTypeDefinition.SwapFee.code)) {
                width += this.fixedColumnWith;
                widthV2 += this.columnWidths[currentIndex++];
            }
            else {
                currentIndex++;
            }


            // 存欠料
            this.metalCommodities.forEach(commodity => {
                // Balance column
                if (this.visibleMetalInFundAccounts.includes(commodity.metalAccountTypeId)|| this.visibleMetalOutFundAccounts.includes(commodity.metalAccountTypeId)) {
                    width += this.fixedColumnWith;
                    widthV2 += this.columnWidths[currentIndex++];
                }
                else {
                    currentIndex++;
                }
            });

            // 来款，付款，存欠款 备注
            widthV2 += this.columnWidths[currentIndex++];
            widthV2 += this.columnWidths[currentIndex++];
            widthV2 += this.columnWidths[currentIndex++];
            widthV2 += this.columnWidths[currentIndex++];

            // console.log('Calculated table width:', width);
            // console.log('Calculated widthV2:', widthV2);




            return widthV2;
        }
    },

    methods: {

        // 是否有编辑权限
        hasEditPermission() {
            return false;
        },

        // 更新目标对象
        updateTargetObj(newTargetObj,forece = false) {

            // 避免重复赋值
            if (this.targetObj === newTargetObj && !forece) {
                return;
            }

            this.showCommoditySettings = false; // 关闭选项

            this.targetObj = newTargetObj;
            this.loading = true;
            this.initData()
            this.loading = false;
        },

        handleSelectVisibleChange(val) {
            this.selectDropdownVisible = val;
        },

        async saveData() {
            if (!this.customerTransitionMgr || !this.customerTransitionMgr.isEdited) {
                ElMessage.warning('无更新数据');
                return;
            }

            const validationError = this.customerTransitionMgr.checkDataComplete();

            if (validationError) {
                if (validationError.msgBoxConfirm) {
                    try {
                        await ElMessageBox.confirm(
                            validationError.errorMsg,
                            '信息错误',
                            {
                                confirmButtonText: '确认',
                                type: 'error'
                            }
                        );

                        // 错误信息直接返回
                        return;

                    } catch (confirmError) {
                        // User cancelled
                        this.submitting = false;
                        return;
                    }
                }
                else {

                    ElMessage.error(validationError.errorMsg);
                    return;
                }
            }
            /*
            else{
                ElMessage.success("校验成功");
                return;
            }
                */



            try {

                const orderResult = await this.metalUiAction.updateMetalCombineOrderBatch(this.customerTransitionMgr.toJson_TransBatch());

                if (orderResult) {

                    ElMessage.success("提交保存成功");

                    // 刷新订单页面 
                    this.refreshList();
                }

            } catch (error) {
                console.error('保存数据失败:', error);
                ElMessage.error('数据保存失败: ' + (error.message || '未知错误'));
            }
        },



        // Excel-like table methods
        getCellClass(rowIndex, colIndex) {
            let classes = 'data-cell'

            if (this.selectedCell &&
                this.selectedCell.row === rowIndex &&
                this.selectedCell.col === colIndex) {
                classes += ' selected'
            }

            return classes
        },

        selectCell(rowIndex, colIndex) {

            if (!this.isEditing(rowIndex, colIndex)) {
                this.editingCell = null;
            }
            this.selectedCell = { row: rowIndex, col: colIndex }
            this.typingMode = false

            // console.log("select cell:",this.selectedCell)
        },

        isEditing(rowIndex, colIndex) {
            return this.editingCell &&
                this.editingCell.row === rowIndex &&
                this.editingCell.col === colIndex
        },

        setEditInputRef(el, rowIndex, colIndex) {
            // Only set the ref when this is the currently editing cell
            if (this.isEditing(rowIndex, colIndex) && el) {
                this.editInput = el
            }
        },

        startEdit(rowIndex, colIndex, initialValue = null) {

            if (!this.hasEditPermission()) {
                console.log('没有编辑权限');
                return;
            }

            this.cellInitValueSet = {}; // Reset the initial value set
            this.selectedCell = { row: rowIndex, col: colIndex }
            this.editingCell = { row: rowIndex, col: colIndex }

            //  console.log('Starting edit for cell:', rowIndex, colIndex);

            // Determine which field to edit based on row/col position
            // This would need to be customized based on your data structure
            const row = this.dataList[rowIndex];

            // Set initial edit value based on cell content
            if (initialValue !== null) {
                this.editValue = initialValue;
            } else {
                // For double-click editing, use existing content
                // This would need to be customized based on your data structure
                this.editValue = ''; // Placeholder
            }

            this.editInput = null // Reset the ref

            // DML 暂时不用下列方法处理，该方法是根据行，列找到对象进行处理
            // this._handleStartEditValueV2(rowIndex, colIndex, this.editValue);

            // 使用下列方法处理，该方法是直接让cell控件对象处理，更为简单              
            if (initialValue != null) {
                this.cellInitValueSet[`${rowIndex}_${colIndex}`] = initialValue;
            }

            this.$nextTick(() => {

                if (this.editInput && this.editInput.focus) {
                    this.editInput.focus()
                }
            })
        },

        _handleStartEditValueV2(rowIndex, colIndex, editValue = null) {
            // 1 贵金属开始前一列的index, 根据实际调整更新该index
            let metalStartIndex = 2
            let metalEndIndex = metalStartIndex + (this.metalCommodities.length) * 6 - 1;

            let metalPayReceiveStartIndex = metalEndIndex + 1;
            let metalPayReceiveEndIndex = metalPayReceiveStartIndex + this.metalCommodities.length * 2 - 1;

            let metalBanlacneStart = metalPayReceiveEndIndex + 1;
            let metalBanlanceEnd = metalBanlacneStart + this.metalCommodities.length - 1;

            let balanceIndex = metalBanlanceEnd + 1;
            let remarkIndex = balanceIndex + 1;

            const isNumberValue = (value) => {
                return !isNaN(parseFloat(value)) && isFinite(value);
            }

            if (colIndex == 0) {

            }
            else if (colIndex == 1) {

            }
            else if (colIndex >= metalStartIndex && colIndex <= metalEndIndex) {

                if (!isNumberValue(editValue)) {
                    return;
                }

                // 每个金属销售，采购各 3 列，一种金属就是 3 列
                let subIndex = (colIndex - metalStartIndex) % 3;
                // 金属类型 每6列一个金属
                let commodityIndex = Math.floor((colIndex - metalStartIndex) / 6);
                // batch 一个金属 销售，采购 对应一个batch ，销售采购各3列
                let batchIndex = (colIndex - metalStartIndex) / 3


                let order = this.dataList[rowIndex];
                // 销售，采购交替 所以 奇数行是销售，偶数行是采购
                let batch = batchIndex % 2 == 0 ? order.getSalesBatchByCommodityId(this.metalCommodities[commodityIndex].id) : order.getPurchaseBatchByCommodityId(this.metalCommodities[commodityIndex].id);

                switch (subIndex) {
                    case 0: // 数量
                        batch?.setCount(new CsDouble(editValue, this.countPrecision));

                        break;
                    case 1: // 价格
                        // batch?.setSinglePriceAfterTax(new CsFundDouble(editValue, this.fundPrecision));
                        break;
                    case 2: // 金额
                        // batch?.setBatchPriceWithTax(new CsFundDouble(editValue, this.fundPrecision));
                        break;
                }

                order?.calculatePriceAndQuantity(true);
                this.customerTransitionMgr.updateTransData();

            }
            else if (colIndex > metalEndIndex && colIndex <= metalPayReceiveEndIndex) {

            }
            else if (colIndex > metalPayReceiveEndIndex && colIndex <= metalBanlanceEnd) {

            }
            else if (colIndex == balanceIndex) {

            }
            else if (colIndex == remarkIndex) {

            }
        },

        finishEdit(rowIndex, colIndex, event) {

            // console.log("finishEdit");
            // 如果点击的是 el-select 或 el-option，不退出编辑
            // 如果 select 下拉弹层正在显示，不退出编辑
            if (this.selectDropdownVisible) return;



            // Apply edited value to the appropriate data field
            // This would need to be customized based on your data structure
            this.editingCell = null
            this.selectedCell = { row: rowIndex, col: colIndex }
            this.typingMode = false
        },

        cancelEdit() {
            this.editingCell = null
            this.typingMode = false
        },

        handleTabKey(event, rowIndex, colIndex) {
            event.preventDefault()
            this.finishEdit(rowIndex, colIndex)

            let newCol = (colIndex + 1) % this.columns.length
            let newRow = rowIndex
            if (newCol === 0) {
                newRow = (rowIndex + 1) % this.dataList.length
            }

            this.$nextTick(() => {
                this.startEdit(newRow, newCol)
            })
        },

        handleArrowKey(event, rowIndex, colIndex, direction) {
            event.preventDefault()
            this.finishEdit(rowIndex, colIndex)

            let newRow = rowIndex
            let newCol = colIndex

            switch (direction) {
                case 'up':
                    newRow = Math.max(rowIndex - 1, 0)
                    break
                case 'down':
                    newRow = Math.min(rowIndex + 1, this.dataList.length - 1)
                    break
                case 'left':
                    newCol = Math.max(colIndex - 1, 0)
                    break
                case 'right':
                    newCol = Math.min(colIndex + 1, this.columns.length - 1)
                    break
            }

            this.$nextTick(() => {
                this.startEdit(newRow, newCol)
            })
        },

        handleDeleteKey(event) {
            // console.log("handleDeleteKey")
            if (this.selectedCell && !this.editingCell) {
                event.preventDefault()
                this.clearCell()
            }
        },

        handleGlobalKeydown(event) {
            //console.log('handleGlobalKeydown -->  ', event.key);
            // Handle typing when a cell is selected but not in edit mode
            if (this.selectedCell && !this.editingCell &&
                !this.typingMode &&
                event.key.length === 1 &&
                !event.ctrlKey &&
                !event.metaKey) {
                // Start typing mode - begin editing with the typed character
                this.typingMode = true
                const { row, col } = this.selectedCell
                this.startEdit(row, col, event.key)
                event.preventDefault()
            }
        },

        getCellAddress() {
            if (!this.selectedCell) return ''
            const { row, col } = this.selectedCell
            // This would need to be customized based on your column structure
            return `R${row + 1}C${col + 1}`
        },

        copyCell() {

            if (!this.selectedCell) return
            const { row, col } = this.selectedCell
            // Copy logic would need to be customized based on your data structure
            this.clipboard = 'copied value' // Placeholder
        },

        pasteCell() {
            if (!this.selectedCell || this.clipboard === null) return
            const { row, col } = this.selectedCell
            // Paste logic would need to be customized based on your data structure
        },

        clearCell() {
            if (!this.selectedCell) return;

            const { row, col } = this.selectedCell;
            const targetRow = this.dataList[row];

            if (!targetRow) return;


            // Get the column type and commodity index
            const columnKey = this.columnIndexCellTypeSet[col];
            if (columnKey === undefined) return;

            const type = Math.floor(columnKey / 100);
            const commodityIndex = columnKey % 100;

            // console.log('columnKey', columnKey, type, commodityIndex);

            switch (type) {
                // Date column
                case TransactionCellType.Date:
                    targetRow.operateDate = null;
                    break;

                // Title/Abstract column
                case TransactionCellType.Title:
                    targetRow.title = '';
                    break;

                // Sales commodity columns
                case TransactionCellType.SalesCommodityCount:
                    const salesBatch = targetRow.getSalesBatchByCommodityId(this.metalCommodities[commodityIndex].id);
                    if (salesBatch) {
                        salesBatch.setCount(null);
                        targetRow.updateOrderInfo(this.metalCommodities);
                        this.customerTransitionMgr.updateTransData();
                    }
                    break;

                case TransactionCellType.SaleCommodityPrice:
                    const salesPriceBatch = targetRow.getSalesBatchByCommodityId(this.metalCommodities[commodityIndex].id);
                    if (salesPriceBatch) {
                        salesPriceBatch.setSinglePriceAfterTax(null);
                        targetRow.updateOrderInfo(this.metalCommodities);
                        this.customerTransitionMgr.updateTransData();
                    }
                    break;

                case TransactionCellType.SalesCommodityBatchPrice:
                    const salesAmountBatch = targetRow.getSalesBatchByCommodityId(this.metalCommodities[commodityIndex].id);
                    if (salesAmountBatch) {
                        salesAmountBatch.setBatchPriceWithTax(null);
                        targetRow.updateOrderInfo(this.metalCommodities);
                        this.customerTransitionMgr.updateTransData();
                    }
                    break;

                // Purchase commodity columns
                case TransactionCellType.PurchaseCommodityCount:
                    const purchaseBatch = targetRow.getPurchaseBatchByCommodityId(this.metalCommodities[commodityIndex].id);
                    if (purchaseBatch) {
                        purchaseBatch.setCount(null);
                        targetRow.updateOrderInfo(this.metalCommodities);
                        this.customerTransitionMgr.updateTransData();
                    }
                    break;

                case TransactionCellType.PurchaseCommodityPrice:
                    const purchasePriceBatch = targetRow.getPurchaseBatchByCommodityId(this.metalCommodities[commodityIndex].id);
                    if (purchasePriceBatch) {
                        purchasePriceBatch.setSinglePriceAfterTax(null);
                        targetRow.updateOrderInfo(this.metalCommodities);
                        this.customerTransitionMgr.updateTransData();
                    }
                    break;

                case TransactionCellType.PurchaseCommodityBatchPrice:
                    const purchaseAmountBatch = targetRow.getPurchaseBatchByCommodityId(this.metalCommodities[commodityIndex].id);
                    if (purchaseAmountBatch) {
                        purchaseAmountBatch.setBatchPriceWithTax(null);
                        targetRow.updateOrderInfo(this.metalCommodities);
                        this.customerTransitionMgr.updateTransData();
                    }
                    break;

                // Metal in/out columns
                case TransactionCellType.MetalIn:
                    this.updateMetalInCount(targetRow, this.metalCommodities[commodityIndex].metalAccountTypeId, null);
                    targetRow.updateOrderInfo(this.metalCommodities);
                    this.customerTransitionMgr.updateTransData();
                    break;

                case TransactionCellType.MetalOut:
                    this.updateMetalOutCount(targetRow, this.metalCommodities[commodityIndex].metalAccountTypeId, null);
                    targetRow.updateOrderInfo(this.metalCommodities);
                    this.customerTransitionMgr.updateTransData();
                    break;

                // Receipt column
                case TransactionCellType.Receipt:
                    targetRow.receivedAmount = null;
                    targetRow.updateOrderInfo(this.metalCommodities);
                    this.customerTransitionMgr.updateTransData();
                    break;

                // Payment column
                case TransactionCellType.Payment:
                    targetRow.paymentAmount = null;
                    targetRow.updateOrderInfo(this.metalCommodities);
                    this.customerTransitionMgr.updateTransData();
                    break;

                // Metal balance column (only editable for initial period records)
                case TransactionCellType.MetalBanlance:
                    if (targetRow.isPeriodInitial) {
                        // 注意，期初不能为null，所以传0
                        this.updateMetalBalance(targetRow, this.metalCommodities[commodityIndex].metalAccountTypeId, 0);
                        this.customerTransitionMgr.updateTransData();
                    }
                    break;

                // Balance column (only editable for initial period records)
                case TransactionCellType.Balance:
                    if (targetRow.isPeriodInitial) {
                        targetRow.balanceAfter = CsFundDouble.zero();
                        targetRow.isEdited = true;
                        this.customerTransitionMgr.updateTransData();
                    }
                    break;

                case TransactionCellType.SwapFee:
                    targetRow.swapFee.fundDouble = null;
                    targetRow.isEdited = true;
                    this.customerTransitionMgr.updateTransData();
                    break;

                // Remark column
                case TransactionCellType.Remark:
                    targetRow.remark = '';
                    break;
            }
        },

        addRow() {
            // Add row logic would need to be customized based on your data structure
        },

        // 初始化数据
        async initData() {

            // 清空数据
            this.dateRange = [];
            this.dataList = [];
            this.metalCommodities = [];
            this.visibleSalesCommodities = [];
            this.visiblePurchaseCommodities = [];
            this.visibleMetalInFundAccounts = [];
            this.visibleMetalOutFundAccounts = [];
            this.showCommoditySettings = false;
            this.initError = false;

            this.selectedCell = null;
            this.editingCell = null;
            this.editValue = '';
            this.clipboard = '';
            this.editInput = null;
            this.typingMode = false;
            this.cellInitValueSet = {},
                this.columnIndexSet = {};
            this.columnIndexCellTypeSet = {};
            this.selectDropdownVisible = false;

            // 初始化数据

            this.calColumnIndexSet();  // 先初始化一次列index
            this.initError = false; // Reset error state
            this.customerTransitionMgr = new CustomerTransictionMgr({
                commodityUiAction: this.commodityUiAction,
                metalUiAction: this.metalUiAction,
                targetObj: this.targetObj
            });

            this.initError = !await this.customerTransitionMgr.initData();
            this.metalCommodities = this.customerTransitionMgr.metalCommodities;
            this.dataList = this.customerTransitionMgr.orders;
            this.total = this.customerTransitionMgr.orders.length;

            this.calColumnIndexSet();  // 数据加载完后再初始化一次列index


            // Load saved column widths
            // this.loadColumnWidths();

            // 插入空行
            this.customerTransitionMgr.fillEmptyLine();
            this.customerTransitionMgr.updateTransData();

            this.initDefaultCommodityGroups();
        },

        // Add this method to retry initialization
        async retryInit() {
            const success = await this.initData();
            if (!success) {
                ElMessage.error('重新加载失败，请稍后重试');
            } else {
                ElMessage.success('数据加载成功');
            }
        },

        // 初始化显示lie
        initDefaultCommodityGroups() {
            // 如果 metalCommodities 还没有加载完成，直接返回
            if (!this.metalCommodities || this.metalCommodities.length === 0) {
                return;
            }

            let metalCombineFilesShowConfig = this.targetObj.quickExtentionFields?.metalCombineFilesShowConfig ?? null;



            if (metalCombineFilesShowConfig) {
                this.visibleSalesCommodities = metalCombineFilesShowConfig.visibleSalesCommodities || [];
                this.visiblePurchaseCommodities = metalCombineFilesShowConfig.visiblePurchaseCommodities || [];
                this.visibleMetalInFundAccounts = metalCombineFilesShowConfig.visibleMetalInFundAccounts || [];
                this.visibleMetalOutFundAccounts = metalCombineFilesShowConfig.visibleMetalOutFundAccounts || [];
                return;
            }
            else {
                // 清空当前选择
                this.visibleSalesCommodities = [];
                this.visiblePurchaseCommodities = [];
                this.visibleMetalInFundAccounts = [];
                this.visibleMetalOutFundAccounts = [];

                // 1. 默认显示黄金销售和回收group, 黄金商品的standard 是 AU
                const goldCommodity = this.metalCommodities.find(commodity => commodity.standard === 'AU');

                // 清空当前选择
                this.visibleSalesCommodities = [];
                this.visiblePurchaseCommodities = [];
                this.visibleMetalInFundAccounts = [];
                this.visibleMetalOutFundAccounts = [];

                if (goldCommodity) {
                    // 默认显示黄金商品的销售和回购group
                    //this.visibleSalesCommodities.push(goldCommodity.id);
                    this.visiblePurchaseCommodities.push(goldCommodity.id);

                    // 默认显示黄金商品的来料和付料group
                    if (goldCommodity.metalAccountTypeId) {
                        this.visibleMetalInFundAccounts.push(goldCommodity.metalAccountTypeId);
                        //  this.visibleMetalOutFundAccounts.push(goldCommodity.metalAccountTypeId);
                    }
                }
            }
        },

        /*
         默认商品group  显示逻辑
       1. 默认显示黄金销售和回收group, 黄金商品的standard 是 AU
       2. 根据getList 反馈的商品优化可显示的商品group:
           1) 如果商品为空，按默认商品group 显示
           2) 如果商品不为空，遍历商品，如果 商品的属性purchaseCommodities 中的商品 id 
             包含与 metalCommodities 中的一致，显示该商品回购group; 
             如果商品 salesCommodities 中的商品 id 包含与 metalCommodities 中的一致，
             显示该商品销售group
         */
        /*
        initDefaultCommodityGroups() {
            // 如果 metalCommodities 还没有加载完成，直接返回
            if (!this.metalCommodities || this.metalCommodities.length === 0) {
                return;
            }

            // 1. 默认显示黄金销售和回收group, 黄金商品的standard 是 AU
            const goldCommodity = this.metalCommodities.find(commodity => commodity.standard === 'AU');

            // 清空当前选择
            this.visibleSalesCommodities = [];
            this.visiblePurchaseCommodities = [];
            this.visibleMetalInFundAccounts = [];
            this.visibleMetalOutFundAccounts = [];

            if (goldCommodity) {
                // 默认显示黄金商品的销售和回购group
                //this.visibleSalesCommodities.push(goldCommodity.id);
                this.visiblePurchaseCommodities.push(goldCommodity.id);

                // 默认显示黄金商品的来料和付料group
                if (goldCommodity.metalAccountTypeId) {
                    this.visibleMetalInFundAccounts.push(goldCommodity.metalAccountTypeId);
                    //  this.visibleMetalOutFundAccounts.push(goldCommodity.metalAccountTypeId);
                }
            }

            // 2. 根据getList 反馈的商品优化可显示的商品group
            if (!this.dataList || this.dataList.length === 0) {
                // 2.1) 如果商品为空，按默认商品group 显示 (已经设置过了)
                return;
            }

            // 2.2) 如果商品不为空，遍历商品
            const salesCommodityIds = new Set();
            const purchaseCommodityIds = new Set();

            // 收集所有出现过的商品ID
            this.dataList.forEach(order => {
                // 检查销售商品
                if (order.salesCommodities && Array.isArray(order.salesCommodities)) {
                    order.salesCommodities.forEach(salesItem => {
                        if (salesItem.commodity && salesItem.commodity.id && salesItem.count?.value > 0) {
                            salesCommodityIds.add(salesItem.commodity.id);
                        }
                    });
                }

                // 检查回购商品
                if (order.purchaseCommodities && Array.isArray(order.purchaseCommodities)) {
                    order.purchaseCommodities.forEach(purchaseItem => {
                        if (purchaseItem.commodity && purchaseItem.commodity.id && purchaseItem.count?.value > 0) {
                            purchaseCommodityIds.add(purchaseItem.commodity.id);
                        }
                    });
                }
            });

            // 更新可见的商品group
            this.metalCommodities.forEach(commodity => {
                const commodityId = commodity.id;
                const metalAccountTypeId = commodity.metalAccountTypeId;

                // 如果该商品在销售商品中出现过，显示销售group
                if (salesCommodityIds.has(commodityId)) {
                    if (!this.visibleSalesCommodities.includes(commodityId)) {
                        this.visibleSalesCommodities.push(commodityId);

                        // 如果该金属账户类型出现过，显示来料和付料group
                        if (metalAccountTypeId) {
                            if (!this.visibleMetalOutFundAccounts.includes(metalAccountTypeId)) {
                                this.visibleMetalOutFundAccounts.push(metalAccountTypeId);
                            }
                        }
                    }
                }

                // 如果该商品在回购商品中出现过，显示回购group
                if (purchaseCommodityIds.has(commodityId)) {
                    if (!this.visiblePurchaseCommodities.includes(commodityId)) {
                        this.visiblePurchaseCommodities.push(commodityId);

                        if (metalAccountTypeId) {
                            if (!this.visibleMetalInFundAccounts.includes(metalAccountTypeId)) {
                                this.visibleMetalInFundAccounts.push(metalAccountTypeId);
                            }
                        }
                    }
                }
            });
        },
        */

        // 获取贵金属商品信息
        async getMetalCommodityInfo() {
            const res = await this.commodityUiAction.getCommoditySpecList(
                new DataPage(1, 0, 100),  // 大一些保障所有贵金属拿到     
                (new SubCommodityFilter({ metalType: SubCommodityMetalFilterTypeEnum.MetalSelfOnly })).toJson()
            )

            if (res?.data?.dataList) {
                this.metalCommodities = res.data.dataList;
                return null;
            }

            return "get metal commodity info failed"
        },

        ///////  贵金属收支列
        // Get metal fund account for a specific row and commodity
        getMetalFundAccount(row, metalAccountTypeId) {
            //console.log("get metal fund account", metalAccountTypeId);
            return row.getMetalBalanceByMetalFoundTypeId(metalAccountTypeId);
        },

        // Get in count (来料) for a metal fund account
        getMetalInCount(row, metalAccountTypeId) {
            const fundAccount = this.getMetalFundAccount(row, metalAccountTypeId);
            return fundAccount?.inCount?.value ?? '';
        },

        // Get out count (付料) for a metal fund account
        getMetalOutCount(row, metalAccountTypeId) {
            const fundAccount = this.getMetalFundAccount(row, metalAccountTypeId);
            return fundAccount?.outCount?.value ?? '';
        },

        // Update in count (来料) for a metal fund account
        updateMetalInCount(row, metalAccountTypeId, value) {
            const fundAccount = this.getMetalFundAccount(row, metalAccountTypeId);
            if (fundAccount) {
                if (value != null) { fundAccount.inCount = new CsDouble(value, this.countPrecision); }
                else {
                    // 清空删除
                    fundAccount.inCount = null;

                }
            }
        },

        // Update out count (付料) for a metal fund account
        updateMetalOutCount(row, metalAccountTypeId, value) {
            const fundAccount = this.getMetalFundAccount(row, metalAccountTypeId);
            if (fundAccount) {
                if (value == null) {
                    // 清空删除
                    fundAccount.outCount = null;
                }
                else {
                    fundAccount.outCount = new CsDouble(value, this.countPrecision);
                }
            }
        },

        // 存欠料
        getMetalBalance(row, metalAccountTypeId) {
            const fundAccount = this.getMetalFundAccount(row, metalAccountTypeId);
            return fundAccount ? fundAccount.balanceAfter?.value : 0;
        },

        // 更新存欠料
        updateMetalBalance(row, metalAccountTypeId, value) {
            const fundAccount = this.getMetalFundAccount(row, metalAccountTypeId);
            if (fundAccount) {
                if (value == null) {
                    // 清空删除
                    fundAccount.balanceAfter = null;
                }
                else {
                    fundAccount.balanceAfter = new CsDouble(value, this.countPrecision);
                }

            }

            row.isEdited = true;
        },

        // 显示配置更新
        handleVisibilityChange(type, newVal, oldVal) {
            // Save the column visibility settings to local storage or other persistent storage
            if (!this.showCommoditySettings) {
                // 只有设置项展开时才可以进行操作
                return;
            }

            // Notify that column visibility has changed
            console.log(`Column visibility changed for ${type}:`, newVal);

            this.metalUiAction.updateCustomerMetalCombineFilesShowConfig(
                this.targetObj, {
                visibleSalesCommodities: this.visibleSalesCommodities,
                visiblePurchaseCommodities: this.visiblePurchaseCommodities,
                visibleMetalInFundAccounts: this.visibleMetalInFundAccounts,
                visibleMetalOutFundAccounts: this.visibleMetalOutFundAccounts
            }
            );
        },

        ///////

        async getList() {
            let ret = null;
            try {
                this.loading = true;
                const result = await this.customerTransitionMgr.refreshCustomerData(
                    this.queryParams.pageNum,
                    this.queryParams.pageSize,
                    this.dateRange
                );

                if (result && result.dataList) {
                    this.dataList = result.dataList;
                    this.total = Number(result.total) || 0;
                    ret = result;
                } else {
                    ElMessage.error('获取综合单据列表失败');
                }
            } catch (error) {
                console.error('获取综合单据列表失败', error);
                ElMessage.error('获取综合单据列表失败');
            } finally {
                this.loading = false;
                return ret;
            }
        },

        getColumnIndex(type, commodityIndex = null) {
            let ret = null
            if (commodityIndex !== null) {
                ret = this.columnIndexSet[type * 100 + commodityIndex];
            }
            else {
                ret = this.columnIndexSet[type * 100];
            }

            return ret;
        },

        //columnIndexSet: 把列index 计算好后放入columnIndexSet 中，通过type * 100作为key, 对于多个贵金属的重复列，使用 type * 100 + commodityIndex 作为key
        // columnIndexCellTypeSet: 反向索引 columnIndexSet, 把列index 作为key, type * 100 + commodityIndex 作为value
        calColumnIndexSet() {
            // Clear the existing set
            this.columnIndexSet = {};
            this.columnIndexCellTypeSet = {};

            // Fixed columns
            this.columnIndexSet[TransactionCellType.Date * 100] = 0;
            this.columnIndexSet[TransactionCellType.Title * 100] = 1;

            this.columnIndexCellTypeSet[0] = TransactionCellType.Date * 100;
            this.columnIndexCellTypeSet[1] = TransactionCellType.Title * 100;

            // Calculate dynamic column indices
            let currentIndex = 2; // Start after Date and Title columns

            // Metal commodity columns (sales and purchase groups)
            this.metalCommodities.forEach((commodity, commodityIndex) => {
                // Sales group (3 columns per commodity)

                this.columnIndexSet[TransactionCellType.SalesCommodityCount * 100 + commodityIndex] = currentIndex++;
                this.columnIndexSet[TransactionCellType.SaleCommodityPrice * 100 + commodityIndex] = currentIndex++;
                this.columnIndexSet[TransactionCellType.SalesCommodityBatchPrice * 100 + commodityIndex] = currentIndex++;


                this.columnIndexCellTypeSet[currentIndex - 3] = TransactionCellType.SalesCommodityCount * 100 + commodityIndex;
                this.columnIndexCellTypeSet[currentIndex - 2] = TransactionCellType.SaleCommodityPrice * 100 + commodityIndex;
                this.columnIndexCellTypeSet[currentIndex - 1] = TransactionCellType.SalesCommodityBatchPrice * 100 + commodityIndex;


                // Purchase group (3 columns per commodity)

                this.columnIndexSet[TransactionCellType.PurchaseCommodityCount * 100 + commodityIndex] = currentIndex++;
                this.columnIndexSet[TransactionCellType.PurchaseCommodityPrice * 100 + commodityIndex] = currentIndex++;
                this.columnIndexSet[TransactionCellType.PurchaseCommodityBatchPrice * 100 + commodityIndex] = currentIndex++;

                this.columnIndexCellTypeSet[currentIndex - 3] = TransactionCellType.PurchaseCommodityCount * 100 + commodityIndex;
                this.columnIndexCellTypeSet[currentIndex - 2] = TransactionCellType.PurchaseCommodityPrice * 100 + commodityIndex;
                this.columnIndexCellTypeSet[currentIndex - 1] = TransactionCellType.PurchaseCommodityBatchPrice * 100 + commodityIndex;

            });

            // Metal fund account columns (in and out)
            this.metalCommodities.forEach((commodity, commodityIndex) => {
                // In count column (来料)
                this.columnIndexSet[TransactionCellType.MetalIn * 100 + commodityIndex] = currentIndex++;

                // Out count column (付料)
                this.columnIndexSet[TransactionCellType.MetalOut * 100 + commodityIndex] = currentIndex++;

                this.columnIndexCellTypeSet[currentIndex - 2] = TransactionCellType.MetalIn * 100 + commodityIndex;
                this.columnIndexCellTypeSet[currentIndex - 1] = TransactionCellType.MetalOut * 100 + commodityIndex;

            });

            // Fixed columns after metal commodities
            this.columnIndexSet[TransactionCellType.Receipt * 100] = currentIndex++;
            this.columnIndexSet[TransactionCellType.Payment * 100] = currentIndex++;

            this.columnIndexCellTypeSet[currentIndex - 2] = TransactionCellType.Receipt * 100;
            this.columnIndexCellTypeSet[currentIndex - 1] = TransactionCellType.Payment * 100;


            // Add swap fee column
            this.columnIndexSet[TransactionCellType.SwapFee * 100] = currentIndex++;
            this.columnIndexCellTypeSet[currentIndex - 1] = TransactionCellType.SwapFee * 100;

            // Metal balance columns
            this.metalCommodities.forEach((commodity, commodityIndex) => {

                this.columnIndexSet[TransactionCellType.MetalBanlance * 100 + commodityIndex] = currentIndex++;

                this.columnIndexCellTypeSet[currentIndex - 1] = TransactionCellType.MetalBanlance * 100 + commodityIndex;

            });

            // Final fixed columns
            this.columnIndexSet[TransactionCellType.Balance * 100] = currentIndex++;
            this.columnIndexSet[TransactionCellType.Remark * 100] = currentIndex++;

            this.columnIndexCellTypeSet[currentIndex - 2] = TransactionCellType.Balance * 100;
            this.columnIndexCellTypeSet[currentIndex - 1] = TransactionCellType.Remark * 100;

            // 设置列宽                 
            this.columnWidths[0] = this.dateColumnWidth;
            this.columnWidths[1] = this.titleColumnWidth;
            this.columnWidths[currentIndex-1] = this.remarkColumnWidth;
            for (let i = 2; i < currentIndex-1; i++) {
                this.columnWidths[i] = this.defaultColumnWidth;
            }


            // console.log('Calculated columnIndexSet:', this.columnIndexSet);
        },

        handleSearch() {
            this.queryParams.pageNum = 1
            this.getList()
        },

        resetSearch() {
            this.filter.clear()
            this.dateRange = []
            this.queryParams.pageNum = 1
            this.getList()
        },

        refreshList() {
            deleteMetalCombineOrderNetworkCache();
            this.getList()
        },

        createMetalCombineOrder() {
            // uiNavigation.showMetalCombineDetailPage(this.$router)
        },

        showDetail(row) {
            //  uiNavigation.showMetalCombineDetailPage(this.$router, { id: row.id })
        },

        handleRowClick(row) {
            this.showDetail(row)
        },

        formatDate(dateStr) {
            if (!dateStr) return ''
            return DateUtil.formatDate(dateStr, 'yyyy-MM-dd')
        },

        formatCurrency(value) {
            return Util.getFundString(value)
        },

        // 开始调整列宽
        startResize(e, colIndex) {
            e.preventDefault();


            this.resizingColumn = colIndex;
            this.resizingStartX = e.clientX;
            this.resizingStartWidth = this.columnWidths[colIndex] || 120;

            // console.log('startResize colIndex:, startWidth:', colIndex, this.resizingStartWidth)

            document.addEventListener('mousemove', this.onMouseMove);
            document.addEventListener('mouseup', this.stopResize);
        },

        // 鼠标移动时调整列宽
        onMouseMove(e) {
            if (!this.resizingColumn && this.resizingColumn !== 0) return;

            const diff = e.clientX - this.resizingStartX;
            const newWidth = Math.max(50, this.resizingStartWidth + diff); // 最小宽度50px

            // 更新对应列宽
            this.columnWidths[this.resizingColumn] = newWidth;

            // console.log('column width', this.resizingColumn, this.columnWidths[this.resizingColumn]);

        },

        // 停止调整列宽
        stopResize() {
            this.resizingColumn = null;
            document.removeEventListener('mousemove', this.onMouseMove);
            document.removeEventListener('mouseup', this.stopResize);

            // Save column widths to localStorage after resizing
            this.saveColumnWidths();
        },

        // Save column widths to localStorage
        saveColumnWidths() {
            try {
                const widthsToSave = {};
                // Only save widths that are different from default (120px)
                Object.keys(this.columnWidths).forEach(key => {
                    if (this.columnWidths[key] !== 120) {
                        widthsToSave[key] = this.columnWidths[key];
                    }
                });

                localStorage.setItem('customerTransactionColumnWidths', JSON.stringify(widthsToSave));
            } catch (e) {
                console.warn('Failed to save column widths to localStorage:', e);
            }
        },

        // Load column widths from localStorage
        loadColumnWidths() {
            try {
                const savedWidths = localStorage.getItem('customerTransactionColumnWidths');
                if (savedWidths) {
                    const parsedWidths = JSON.parse(savedWidths);
                    // Merge with existing columnWidths
                    Object.keys(parsedWidths).forEach(key => {
                        this.columnWidths[key] = parsedWidths[key];
                    });
                }
            } catch (e) {
                console.warn('Failed to load column widths from localStorage:', e);
            }
        },


        showContextMenu(event, rowIndex) {

            event.preventDefault();

            this.contextMenu.visible = true;
            this.contextMenu.x = event.clientX;
            this.contextMenu.y = event.clientY;
            this.contextMenu.rowIndex = rowIndex;

            // Add click outside listener to close menu
            this.$nextTick(() => {
                document.addEventListener('click', this.hideContextMenu);
            });
        },

        hideContextMenu() {
            this.contextMenu.visible = false;
            this.contextMenu.rowIndex = -1;
            document.removeEventListener('click', this.hideContextMenu);
        },

        async createOrder() {
            this.isEditDialog = false
            this.currentEditRow = null
            this.currentEditRowIndex = -1
            this.showTransactionDialog = true
            this.$refs.transactionDialog.showDialog(this.currentEditRow)
        },

        editRow(rowIndex) {
            this.hideContextMenu()
            this.isEditDialog = true
            this.currentEditRow = this.dataList[rowIndex]
            this.currentEditRowIndex = rowIndex
            this.showTransactionDialog = true
            this.$refs.transactionDialog.showDialog(this.currentEditRow)
        },

        rowEditAble(rowIndex) {
            // 未结算单据，未结算期初可以编辑
            console.log('rowEditAble', this.dataList[rowIndex]);
            return (this.dataList[rowIndex].id || this.dataList[rowIndex].isPeriodInitial)&&
                !this.dataList[rowIndex].periodId;
        },

        rowDeleteAble(rowIndex) {
            return this.dataList[rowIndex].id
                && this.dataList[rowIndex].combineOrderType.code === CombineOrderType.NormalRnd.code
                && !this.dataList[rowIndex].periodId;
        },

        handleTransactionConfirm() {
            // 刷新订单页面 
            this.refreshList();
        },



        deleteRow(rowIndex) {
            // Hide context menu first
            this.hideContextMenu();

            // Check if it's a period initial row which shouldn't be deleted
            if (this.dataList[rowIndex].isPeriodInitial) {
                ElMessage.warning('期初数据行不能删除');
                return;
            }

            // Show confirmation dialog
            ElMessageBox.confirm(
                '确定要删除这一行数据吗？此操作不可撤销',
                '删除确认',
                {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }
            ).then(() => {
                // Remove the row from dataList

                this.customerTransitionMgr.removeOrder(this.dataList[rowIndex]);

                this.dataList = this.customerTransitionMgr.orders;

                // Update total count
                this.total = this.dataList.length;

                // Recalculate column indexes since structure changed
                this.calColumnIndexSet();

                // ElMessage.success('删除成功');
            }).catch(() => {
                // User cancelled deletion
            });
        }

    }
}
</script>

<style scoped>
.header-content {
    position: relative;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.resize-handle {
    position: absolute;
    right: 0;
    top: 0;
    width: 5px;
    height: 100%;
    cursor: col-resize;
    user-select: none;
}

.resize-handle:hover {
    background-color: #409eff;
}

/* Style for edited row header cells */
.header-cell.edited-row {
    background-color: #fff7e6;
    /* Light orange background */
    font-weight: bold;
    color: #fa8c16;
    /* Darker orange text */
}

/* Alternative style with a border indicator */
.header-cell.edited-row {
    background-color: #fff7e6;
    border-left: 3px solid #fa8c16;
    /* Orange left border */
}

.header-cell {
  font-size: 13px; /* Ensure header cells have smaller font */
}

.excel-table-header .header-cell {
    position: relative;
    padding: 0;
}

.excel-table th,
.excel-table td {
    position: relative;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.excel-like-page {
    padding: 0px;
    background-color: #f5f7fa;
    min-height: 100vh;
}

.excel-container {
    background: white;
    border-radius: 4px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    overflow: hidden;
    display: inline-block;
    max-width: 100%;
}

.excel-toolbar {
    padding: 10px;
    border-bottom: 1px solid #dcdfe6;
    background-color: #ffffff;
}

.excel-table-container-wrapper {
    position: relative;
    height: calc(100vh - 160px);
    ;
    width: 100%;
    overflow-x: auto;
    overflow-y: hidden;
}

.excel-table-header {
    overflow: hidden;
    background-color: #f5f7fa;
}

.excel-table-container {
    overflow: auto;
    overflow-x: hidden;
    height: calc(100% - 30px);
    /* Subtract header height */
    outline: none;
}

.excel-table {
    border-collapse: collapse;
    table-layout: fixed;
    display: table;
}

.excel-table th,
.excel-table td {
    border: 1px solid #dcdfe6;
    padding: 0;
    text-align: center;
    vertical-align: middle;
    height: 30px;
    position: relative;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.excel-table .header-cell {
    background-color: #f5f7fa;
    font-weight: bold;
    user-select: none;
}

.excel-table .corner-cell {
    width: 40px;
}

.excel-table .data-cell {
    padding: 0px;
    cursor: cell;
    position: relative;
    font-size: 12px;
}

.excel-table .data-cell:hover {
    background-color: #f5f7fa;
}

.excel-table .data-cell.selected {
    border: 2px solid #409eff !important;
    z-index: 10;
}

.cell-input {
    width: 100%;
    height: 100%;
}

.cell-input :deep(.el-input__wrapper) {
    box-shadow: none;
    border: none;
    padding: 0 4px;
    height: 100%;
    background-color: #e6f7ff;
}

.excel-status-bar {
    padding: 8px 12px;
    border-top: 1px solid #dcdfe6;
    background-color: #f5f7fa;
    font-size: 14px;
    color: #606266;
}

:deep(.el-button-group .el-button) {
    border-radius: 0;
}

:deep(.el-button-group .el-button:first-child) {
    border-top-left-radius: 4px;
    border-bottom-left-radius: 4px;
}

:deep(.el-button-group .el-button:last-child) {
    border-top-right-radius: 4px;
    border-bottom-right-radius: 4px;
}

.metal-combine-container-wrapper {
    height: 100%;
    overflow: auto;
}

.metal-combine-container {
    min-width: 800px;
    padding-top: 0px;
    padding-left: 0px;
}

:deep(.sales-group) {
    background-color: #f0f9ff !important;
}

:deep(.purchase-group) {
    background-color: #f0fdf4 !important;
}

:deep(.sales-group .cell),
:deep(.purchase-group .cell) {
    font-weight: 500;
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px solid #ebeef5;
    padding-top: 10px;
    padding-bottom: 10px;
    padding-left: 10px;
}

:deep(.metal-in-group) {
    background-color: #fff7e6 !important;
}

:deep(.metal-out-group) {
    background-color: #f9f0ff !important;
}

:deep(.metal-in-group .cell),
:deep(.metal-out-group .cell) {
    font-weight: 500;
}

/* Add styles for error  */
.error-container {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    min-height: 400px;
    background-color: #f5f5f5;
}

.error-content {
    text-align: center;
    padding: 30px;
    background: white;
    border-radius: 8px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    max-width: 500px;
}

.error-message {
    display: flex;
    align-items: flex-start;
    gap: 15px;
}

.error-icon {
    font-size: 36px;
    color: #909399;
    margin-top: 5px;
}

.error-text h3 {
    margin: 0 0 8px 0;
    color: #606266;
    font-size: 18px;
}

.error-text p {
    margin: 0;
    color: #909399;
    font-size: 14px;
    line-height: 1.5;
}

/* 灰色单元格 Style for disabled cells */
.disabled-cell {
    background-color: #eeeeee;
    /* Light gray background */
    color: #c0c4cc;
    /* Gray text */
    font-style: italic;
}

/* Style for disabled text inside disabled cells */
.disabled-cell .disabled-text {
    color: inherit;
    /* Inherit the color from the parent */
}

/* Make sure the cell content is also disabled */
.disabled-cell span {
    color: #97999e;
}

/**  资金账户 */
.receipt-cell-container {
    display: flex;
    flex-direction: column;
    padding: 2px;
}

.receipt-cell-container .cell-input {
    margin-bottom: 2px;
}

.account-selector {
    width: 100%;
    font-size: 12px;
    padding: 2px;
    border: 1px solid #dcdfe6;
    border-radius: 3px;
    background-color: white;
}

.account-selector:disabled {
    background-color: #f5f7fa;
    color: #c0c4cc;
}

.receipt-display {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.receipt-display .account-name {
    font-size: 11px;
    color: #909399;
    margin-top: 2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/** 右键菜单 */

.context-menu {
    position: fixed;
    background: white;
    border: 1px solid #e4e7ed;
    border-radius: 4px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    z-index: 9999;
    min-width: 120px;
}

.context-menu ul {
    list-style: none;
    padding: 6px 0;
    margin: 0;
}

.context-menu li {
    padding: 8px 16px;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
}

.context-menu li:hover {
    background-color: #f5f7fa;
}

.context-menu li.disabled {
    color: #ccc;
    cursor: not-allowed;
    pointer-events: none;
}
</style>